pleasegpt 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3fe6ac1bdc94405d7be4ae85189cc4f7b55e4d0ebb8805b64848aa4ad457b57
4
- data.tar.gz: 8454842d82d428d31e5c9de69ef3dabcefc471c6222063d865b701f72b2c941e
3
+ metadata.gz: 80324ce62390d5faf8471f67c5224454feb99960993e0d596cc5b420e1c57c25
4
+ data.tar.gz: 8c7aff7f3c3f0b6f4e012da47c1d808c1b2b112a83df4bc7d9981e98b8a8a580
5
5
  SHA512:
6
- metadata.gz: c06a7d1921370d80d3a63ac34ea8bb9c5f1d21aa2c4e9368fb388e5074c809fa7b592bb4f2eec4f1e02e86a431a4ae87bc98f0f761439aa49cbc73df8350ca52
7
- data.tar.gz: ac5ec1c168ec08883c5c44a424058e1ab94e5b57adcd111fd9ce1e97a95804904fc2756b12d14f80f03c69eb1b11096c21044e267718af0d41a3d01ad25a9307
6
+ metadata.gz: 3216455a7dac511673f8cb1499d1749d56eb3a8c9aaed765136f70a764acdfebf91c8b6b0b13fbcfbbf41ad67d4d4b467ef2a658701b054995950210074da945
7
+ data.tar.gz: c4f60381dd7553bc7ad9e4249b0b1e90f0c66bf40ef39e684b301751acea7709dfc105139e34ab7b3364f5c2476861023f0f65c4655991a9fb6a32ed86fac296
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'pleasegpt'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/pleasegpt CHANGED
@@ -9,13 +9,17 @@ case ARGV[0]
9
9
  when 'load-key'
10
10
  PleaseGPT::Api.load_api_key
11
11
  when 'help'
12
- puts <<-HELP
13
- PleaseGPT - A command-line tool for OpenAI's GPT-3 API
12
+ puts <<~HELP
13
+ PleaseGPT - A command-line tool for OpenAI's GPT-3 API.
14
+ Using special characters in your command is not supported. In this case, please use double quotes.
14
15
 
15
- Usage:
16
- pleasegpt [input] # Generate text based on input
17
- pleasegpt load-key # Save OpenAI API key
18
- pleasegpt help # Show this help message
16
+ Usage:
17
+ pleasegpt help Show all commands
18
+ pleasegpt load-key Save OpenAI key in a Env file. (Required)
19
+ pleasegpt "any text or question" Reply your request
20
+ pleasegpt -c "your question" When requesting a command, will reply only the command.
21
+ pleasegpt autocomplete "your-text" Complete your partial request
22
+ pleasegpt suggest "your-text" Suggest a new text based on your request
19
23
  HELP
20
24
  else
21
25
  PleaseGPT::CLI.new.start(ARGV)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/pleasegpt/cli.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pleasegpt'
2
4
  require 'colorize'
3
5
 
@@ -7,6 +9,9 @@ module PleaseGPT
7
9
  def start(args)
8
10
  if args.empty?
9
11
  puts '>>> Please enter a valid command <<<'
12
+ elsif args[0] == '-c'
13
+ input = args[1..].join(' ')
14
+ puts Api.generate_command(input).to_s.colorize(:green)
10
15
  else
11
16
  input = args.join(' ')
12
17
  puts Api.generate_text(input).to_s.colorize(:green)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby/openai'
4
+ require 'openai'
5
+ require 'highline/import'
6
+ require 'dotenv/load'
7
+ require 'dotenv'
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dotenv'
4
+ require 'openai'
5
+
6
+ # rubocop:disable Metrics/MethodLength
7
+
8
+ # Main module for OpenAI Client
9
+ module OpenaiClient
10
+ def self.openai_response(prompt, max_tokens, temperature, responses_qty, stop)
11
+ response = openai_client_new.completions(
12
+ parameters: {
13
+ model: 'text-davinci-003',
14
+ prompt: prompt,
15
+ max_tokens: max_tokens,
16
+ temperature: temperature,
17
+ n: responses_qty,
18
+ stop: stop
19
+ }
20
+ )
21
+ PleaseGPT::Error.check_response(response)
22
+ end
23
+
24
+ def self.openai_client_new
25
+ Dotenv.load(PleaseGPT::Api.join_lib_dir_with_file)
26
+ raise PleaseGPT::Error, 'OPENAI_API_KEY not set' unless ENV['OPENAI_API_KEY']
27
+
28
+ OpenAI::Client.new(access_token: ENV['OPENAI_API_KEY'])
29
+ end
30
+ end
31
+
32
+ # rubocop:enable Metrics/MethodLength
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Gem Version
4
+ module Pleasegpt
5
+ VERSION = '0.2.0'
6
+ end
data/lib/pleasegpt.rb CHANGED
@@ -1,14 +1,27 @@
1
- require 'ruby/openai'
2
- require 'openai'
3
- require 'highline/import'
4
- require 'dotenv/load'
5
- require 'dotenv'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'pleasegpt/version'
4
+ require_relative 'pleasegpt/gems'
5
+ require_relative 'pleasegpt/openai_api'
6
6
 
7
7
  # Main module for PleaseGPT gem
8
8
  module PleaseGPT
9
9
  autoload :CLI, 'pleasegpt/cli'
10
10
 
11
- # API class for OpenAI API requests and responses
11
+ # Error class for OpenAI API requests and response errors
12
+ class Error < StandardError
13
+ def self.check_response(response)
14
+ if response['choices'].nil? || response['choices'].empty?
15
+ raise PleaseGPT::Error, 'Request returned empty response'
16
+ elsif response['choices'][0]['text'].nil?
17
+ raise PleaseGPT::Error, 'Request returned nil text'
18
+ else
19
+ response['choices'][0]['text'].strip
20
+ end
21
+ end
22
+ end
23
+
24
+ # Main module for Dirs and loading/Saving API key
12
25
  module Api
13
26
  def self.load_api_key
14
27
  key = ask('Please paste your OpenAI API key: ')
@@ -39,38 +52,12 @@ module PleaseGPT
39
52
  end
40
53
  end
41
54
 
42
- def self.openai_client
43
- Dotenv.load(join_lib_dir_with_file)
44
- raise 'OPENAI_API_KEY not set' unless ENV['OPENAI_API_KEY']
45
-
46
- OpenAI::Client.new(access_token: ENV['OPENAI_API_KEY'])
47
- end
48
-
49
55
  def self.generate_text(input)
50
- response = openai_client.completions(
51
- parameters: {
52
- model: 'text-davinci-003',
53
- prompt: input,
54
- max_tokens: 300,
55
- temperature: 0.5,
56
- n: 1,
57
- stop: '.'
58
- }
59
- )
60
- Error.check_response(response)
56
+ OpenaiClient.openai_response(input, 300, 0.5, 1, '.')
61
57
  end
62
- end
63
58
 
64
- # Error class for OpenAI API requests and response errors
65
- class Error < StandardError
66
- def self.check_response(response)
67
- if response['choices'].nil? || response['choices'].empty?
68
- raise PleaseGPT::Error, 'Request returned empty response'
69
- elsif response['choices'][0]['text'].nil?
70
- raise PleaseGPT::Error, 'Request returned nil text'
71
- else
72
- response['choices'][0]['text'].strip
73
- end
59
+ def self.generate_command(input)
60
+ OpenaiClient.openai_response(input, 100, 0.5, 1, '\n')
74
61
  end
75
62
  end
76
63
  end
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
- RSpec.describe "pleasegpt executable" do
4
- it "runs with the given arguments" do
5
- expect { system('bin/pleasegpt what is the capital of France?') }
6
- .to output(/\S/).to_stdout
7
- .and output(String).to_stdout
5
+ RSpec.describe 'pleasegpt executable' do
6
+ it 'runs with the given arguments' do
7
+ output = `bin/pleasegpt what is the capital of France?`
8
+ expect(output).to_not be_empty
8
9
  end
9
10
  end
data/spec/lib/cli_test.rb CHANGED
@@ -1,11 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'pleasegpt/cli'
3
- require 'colorize'
4
5
 
5
6
  RSpec.describe PleaseGPT::CLI do
6
- describe "#start" do
7
- context "when given a valid command receives a response in blue" do
8
- let(:args) { ["how much is 2+2?"] }
7
+ describe '#start' do
8
+ context 'when given empty args' do
9
+ let(:args) { [] }
10
+
11
+ it 'returns an error message' do
12
+ expected_output = ">>> Please enter a valid command <<<\n"
13
+ expect { subject.start(args) }.to output(expected_output).to_stdout
14
+ end
15
+ end
16
+
17
+ context 'when given a valid command receives a response in blue' do
18
+ let(:args) { ['how much is 2+2?'] }
9
19
 
10
20
  before do
11
21
  allow(PleaseGPT::Api).to receive(:generate_text).with(args.join(' ')) do
@@ -13,10 +23,9 @@ RSpec.describe PleaseGPT::CLI do
13
23
  end
14
24
  end
15
25
 
16
- it "returns a non-empty response from the OpenAI API with blue colour" do
17
- expect { subject.start(args) }.to output(/.*\n/).to_stdout
18
- expect { subject.start(args) }.to output(/\S/).to_stdout
19
- expect { subject.start(args) }.to output(/\e\[0;34;49m.*\e\[0m\n/).to_stdout
26
+ it 'returns the response from the OpenAI API with blue colour' do
27
+ expected_output = "\e[0;32;49mThe answer is 4.\e[0m\n"
28
+ expect { subject.start(args) }.to output(expected_output).to_stdout
20
29
  end
21
30
  end
22
31
  end
@@ -1,21 +1,68 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'pleasegpt'
3
5
 
6
+ # rubocop:disable Metrics/BlockLength
7
+
4
8
  RSpec.describe PleaseGPT::Api do
5
- describe '#generate_text' do
6
- let(:input) { 'Some prompt for GPT' }
7
- let(:response_text) { 'Generated text' }
8
-
9
- before do
10
- allow_any_instance_of(OpenAI::Client)
11
- .to receive(:completions)
12
- .and_return('choices' => [{ 'text' => response_text }])
9
+ describe 'Api' do
10
+ context 'when API key is valid' do
11
+ let(:key) { 'valid_key' }
12
+
13
+ before do
14
+ allow(PleaseGPT::Api).to receive(:ask).and_return(key)
15
+ allow(File).to receive(:write)
16
+ allow(File).to receive(:open)
17
+ allow(Dotenv).to receive(:load)
18
+ end
19
+
20
+ it 'saves the API key to the file' do
21
+ expect(PleaseGPT::Api).to receive(:save_api_key).with(key)
22
+ PleaseGPT::Api.load_api_key
23
+ end
24
+
25
+ it 'sets the OPENAI_API_KEY environment variable' do
26
+ expect(PleaseGPT::Api).to receive(:env_variable).with(key)
27
+ PleaseGPT::Api.load_api_key
28
+ end
29
+ end
30
+
31
+ context 'when API key is empty' do
32
+ it 'does not save the API key to the file' do
33
+ allow(PleaseGPT::Api).to receive(:ask).and_return('')
34
+ expect { PleaseGPT::Api.load_api_key }.to output("API Key cannot be empty. Please try again.\n").to_stdout
35
+ end
13
36
  end
14
37
 
15
- it 'returns a non-empty response' do
16
- response = PleaseGPT::Api.generate_text(input)
17
- expect(response).not_to be_empty
18
- expect(response).to eq(response_text)
38
+ describe '.generate_text' do
39
+ before do
40
+ allow(PleaseGPT::Api).to receive(:openai_client).and_return(client)
41
+ allow(PleaseGPT::Error).to receive(:check_response).and_return('output text')
42
+ end
43
+
44
+ let(:client) { double('client') }
45
+
46
+ it 'returns generated text' do
47
+ expect(client).to receive(:completions)
48
+ expect(PleaseGPT::Api.generate_text('prompt')).to eq('output text')
49
+ end
50
+ end
51
+
52
+ describe '.openai_client' do
53
+ let(:api_key) { 'key123' }
54
+ let(:client) { double('client') }
55
+
56
+ before do
57
+ ENV['OPENAI_API_KEY'] = api_key
58
+ allow(OpenAI::Client).to receive(:new).and_return(client)
59
+ end
60
+
61
+ it 'returns a new instance of OpenAI::Client' do
62
+ expect(PleaseGPT::Api.openai_client).to eq(client)
63
+ end
19
64
  end
20
65
  end
21
66
  end
67
+
68
+ # rubocop:enable Metrics/BlockLength
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pleasegpt do
6
+ it 'has a version number' do
7
+ expect(Pleasegpt::VERSION).not_to be nil
8
+ end
9
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,17 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rspec'
2
4
  require 'pleasegpt'
3
5
  require 'dotenv/load'
4
6
 
5
- unless ENV['OPENAI_API_KEY']
6
- # Prompt the user to enter their API key
7
- puts 'Please enter your OpenAI API key: '
8
- api_key = gets.chomp
7
+ RSpec.configure do |config|
8
+ # Enable flags like --only-failures and --next-failure
9
+ config.example_status_persistence_file_path = '.rspec_status'
9
10
 
10
- # Set the environment variable for the current process
11
- ENV['OPENAI_API_KEY'] = api_key
12
- end
11
+ # Disable RSpec exposing methods globally on `Module` and `main`
12
+ config.disable_monkey_patching!
13
+
14
+ config.expect_with :rspec do |c|
15
+ c.syntax = :expect
16
+ end
13
17
 
14
- RSpec.configure do |config|
15
18
  config.color = true
16
19
  config.formatter = :documentation
17
20
  end
metadata CHANGED
@@ -1,29 +1,63 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pleasegpt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafael Moreira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-30 00:00:00.000000000 Z
11
+ date: 2023-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ruby-openai
14
+ name: colorize
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.7'
19
+ version: 0.8.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '3.7'
26
+ version: 0.8.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: dotenv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.8'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.8.1
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '2.8'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.8.1
47
+ - !ruby/object:Gem::Dependency
48
+ name: highline
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.1'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.1'
27
61
  - !ruby/object:Gem::Dependency
28
62
  name: openai
29
63
  requirement: !ruby/object:Gem::Requirement
@@ -39,73 +73,89 @@ dependencies:
39
73
  - !ruby/object:Gem::Version
40
74
  version: 0.3.0
41
75
  - !ruby/object:Gem::Dependency
42
- name: dotenv
76
+ name: rake
43
77
  requirement: !ruby/object:Gem::Requirement
44
78
  requirements:
45
79
  - - "~>"
46
80
  - !ruby/object:Gem::Version
47
- version: '2.8'
48
- - - ">="
49
- - !ruby/object:Gem::Version
50
- version: 2.8.1
81
+ version: '13.0'
51
82
  type: :runtime
52
83
  prerelease: false
53
84
  version_requirements: !ruby/object:Gem::Requirement
54
85
  requirements:
55
86
  - - "~>"
56
87
  - !ruby/object:Gem::Version
57
- version: '2.8'
58
- - - ">="
88
+ version: '13.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rspec
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
59
94
  - !ruby/object:Gem::Version
60
- version: 2.8.1
95
+ version: '3.0'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3.0'
61
103
  - !ruby/object:Gem::Dependency
62
- name: highline
104
+ name: rubocop
63
105
  requirement: !ruby/object:Gem::Requirement
64
106
  requirements:
65
107
  - - "~>"
66
108
  - !ruby/object:Gem::Version
67
- version: '2.1'
109
+ version: '1.21'
68
110
  type: :runtime
69
111
  prerelease: false
70
112
  version_requirements: !ruby/object:Gem::Requirement
71
113
  requirements:
72
114
  - - "~>"
73
115
  - !ruby/object:Gem::Version
74
- version: '2.1'
116
+ version: '1.21'
75
117
  - !ruby/object:Gem::Dependency
76
- name: colorize
118
+ name: ruby-openai
77
119
  requirement: !ruby/object:Gem::Requirement
78
120
  requirements:
79
121
  - - "~>"
80
122
  - !ruby/object:Gem::Version
81
- version: 0.8.1
123
+ version: '3.7'
82
124
  type: :runtime
83
125
  prerelease: false
84
126
  version_requirements: !ruby/object:Gem::Requirement
85
127
  requirements:
86
128
  - - "~>"
87
129
  - !ruby/object:Gem::Version
88
- version: 0.8.1
89
- description:
90
- email:
91
- - rafamsilva@gmail.com
130
+ version: '3.7'
131
+ description: |
132
+ A Ruby gem that provides a wrapper around the OpenAI API.
133
+ It allows you to generate natural language text based on a given prompt.
134
+ email: rafamsilva@gmail.com
92
135
  executables:
93
136
  - pleasegpt
94
137
  extensions: []
95
138
  extra_rdoc_files: []
96
139
  files:
140
+ - bin/console
97
141
  - bin/pleasegpt
142
+ - bin/setup
98
143
  - lib/pleasegpt.rb
99
144
  - lib/pleasegpt/cli.rb
145
+ - lib/pleasegpt/gems.rb
146
+ - lib/pleasegpt/openai_api.rb
147
+ - lib/pleasegpt/version.rb
100
148
  - spec/bin/pleasegpt_test.rb
101
149
  - spec/lib/cli_test.rb
102
150
  - spec/lib/pleasegpt_test.rb
151
+ - spec/pleasegpt_spec.rb
103
152
  - spec/spec_helper.rb
104
153
  homepage: https://github.com/rafaover/pleasegpt
105
154
  licenses:
106
155
  - MIT
107
156
  metadata: {}
108
- post_install_message:
157
+ post_install_message: Thanks for installing! Please run `pleasegpt load-key` to configure
158
+ the gem.
109
159
  rdoc_options: []
110
160
  require_paths:
111
161
  - lib
@@ -113,7 +163,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
163
  requirements:
114
164
  - - ">="
115
165
  - !ruby/object:Gem::Version
116
- version: '0'
166
+ version: 2.6.0
117
167
  required_rubygems_version: !ruby/object:Gem::Requirement
118
168
  requirements:
119
169
  - - ">="
@@ -123,5 +173,5 @@ requirements: []
123
173
  rubygems_version: 3.3.7
124
174
  signing_key:
125
175
  specification_version: 4
126
- summary: A simple wrapper around the OpenAI GPT-3 API
176
+ summary: A wrapper around the OpenAI API Chat Model
127
177
  test_files: []