senior 0.1.0 → 0.2.0
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/.rubocop.yml +3 -0
- data/CHANGELOG.md +22 -3
- data/README.md +31 -2
- data/lib/senior/brains/open_ai.rb +17 -8
- data/lib/senior/configuration/main.rb +37 -0
- data/lib/senior/configuration/open_ai.rb +146 -0
- data/lib/senior/errors.rb +9 -0
- data/lib/senior/version.rb +1 -1
- data/lib/senior.rb +30 -0
- data/sig/senior/brains/open_ai.rbs +2 -1
- data/sig/senior/configuration/main.rbs +7 -0
- data/sig/senior/configuration/open_ai.rbs +26 -0
- data/sig/senior/errors.rbs +7 -0
- data/sig/senior.rbs +3 -4
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 448f1287d6404de5d6a2168f69b2517605310f99865992d7e4db5ffee9fc538a
|
4
|
+
data.tar.gz: f7d0392887141cd1ee232438483cebc274a6b39607d81c93a5b9033312c62415
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be9c24e647fe23cbb5e5e8580d775ab0822672856b2bc4f1bc0567a61ad9677e455b08e73aad7e95f51a1a3835809abd640220fcb6c8c249f6276376f5203021
|
7
|
+
data.tar.gz: 8210280b84ae3c47b5442a1a7ae8b6cdf23cd9bdc7b255701d8b6808f7864267e855bc730b424e567abd44d5de8607f7a324256ef5e1762b9a3c92599be81b2d
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,9 +2,6 @@
|
|
2
2
|
|
3
3
|
- Ability to wrap a method invocation. For example, `Senior.suggest_fix { my_broken_method(2) }`
|
4
4
|
- Test generation `Senior.write_tests_for {}`
|
5
|
-
- Configure API keys for the OpenAI
|
6
|
-
- Use different OpenAI models
|
7
|
-
- Parametrize the calls to OpenAI
|
8
5
|
- See price per call
|
9
6
|
- Set API calling and pricing limits
|
10
7
|
- Use different AI APIs, not just OpenAI
|
@@ -13,6 +10,28 @@
|
|
13
10
|
- RBS Signatures
|
14
11
|
- Domain exceptions
|
15
12
|
|
13
|
+
## [0.2.0] - 2023-04-10
|
14
|
+
|
15
|
+
### Added
|
16
|
+
- Added the ability to configure the gem with a block:
|
17
|
+
```ruby
|
18
|
+
Senior.configure do |config|
|
19
|
+
config.open_ai.access_token = ENV.fetch('OPEN_AI_ACCESS_TOKEN')
|
20
|
+
config.open_ai.organization_id = ENV.fetch('OPEN_AI_ORGANIZATION_ID') # Optional
|
21
|
+
config.open_ai.api_version = 'v1'
|
22
|
+
config.open_ai.max_tokens = 1024
|
23
|
+
config.open_ai.model = 'text-davinci-003'
|
24
|
+
config.open_ai.n = 1
|
25
|
+
config.open_ai.request_timeout = 120
|
26
|
+
config.open_ai.temperature = 0.7
|
27
|
+
config.open_ai.uri_base = 'https://api.openai.com/'
|
28
|
+
end
|
29
|
+
```
|
30
|
+
These configurations are used as default values for the OpenAI API calls.
|
31
|
+
|
16
32
|
## [0.1.0] - 2023-04-10
|
17
33
|
|
18
34
|
- Initial release
|
35
|
+
|
36
|
+
[0.2.0]: https://github.com/wilsonsilva/senior/compare/v0.1.0...v0.2.0
|
37
|
+
[0.1.0]: https://github.com/wilsonsilva/senior/compare/eecec20...v0.1.0
|
data/README.md
CHANGED
@@ -2,10 +2,24 @@
|
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/senior)
|
4
4
|
[](https://github.com/wilsonsilva/senior/actions/workflows/main.yml)
|
5
|
+
[](https://codeclimate.com/github/wilsonsilva/senior/test_coverage)
|
6
|
+
[](https://codeclimate.com/github/wilsonsilva/senior/maintainability)
|
5
7
|
|
6
8
|
Provides AI-powered debugging and automatic suggestion of code fixes. It makes use of OpenAI's language model to analyze
|
7
9
|
and modify the source code of broken methods, allowing them to be fixed automatically.
|
8
10
|
|
11
|
+
## Table of Contents
|
12
|
+
|
13
|
+
- [Installation](#installation)
|
14
|
+
- [Usage](#usage)
|
15
|
+
- [Auto-debugging a broken method](#auto-debugging-a-broken-method)
|
16
|
+
- [Suggesting a fix for a broken method](#suggesting-a-fix-for-a-broken-method)
|
17
|
+
- [Development](#development)
|
18
|
+
- [Type checking](#type-checking)
|
19
|
+
- [Contributing](#contributing)
|
20
|
+
- [License](#license)
|
21
|
+
- [Code of Conduct](#code-of-conduct)
|
22
|
+
|
9
23
|
## Installation
|
10
24
|
|
11
25
|
Install the gem and add to the application's Gemfile by executing:
|
@@ -18,8 +32,23 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
18
32
|
|
19
33
|
## Usage
|
20
34
|
|
21
|
-
|
22
|
-
|
35
|
+
- Get your API key from https://platform.openai.com/account/api-keys
|
36
|
+
- (optional) If you belong to multiple organizations, you can get your Organization ID from https://platform.openai.com/account/org-settings
|
37
|
+
- Configure the library by passing your OpenAI API credentials:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
Senior.configure do |config|
|
41
|
+
config.open_ai.access_token = ENV.fetch('OPEN_AI_ACCESS_TOKEN')
|
42
|
+
config.open_ai.organization_id = ENV.fetch('OPEN_AI_ORGANIZATION_ID') # Optional
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Note that `OPEN_AI_ACCESS_TOKEN` and `OPEN_AI_ORGANIZATION_ID` are environment variables that should be set in your
|
47
|
+
environment. You should never hardcode your API credentials directly in your code, as this is a security risk.
|
48
|
+
Instead, store your API credentials securely, such as using environment variables or a separate configuration file that
|
49
|
+
is excluded from source control.
|
50
|
+
|
51
|
+
Once you have configured the library, you can use the Senior module to interact with the OpenAI API.
|
23
52
|
|
24
53
|
### Auto-debugging a broken method
|
25
54
|
To debug a broken method, call Senior.auto_debug and pass in the broken method, its arguments, and optionally its
|
@@ -45,8 +45,8 @@ module Senior
|
|
45
45
|
#
|
46
46
|
def open_ai_client
|
47
47
|
@open_ai_client ||= ::OpenAI::Client.new(
|
48
|
-
access_token:
|
49
|
-
organization_id:
|
48
|
+
access_token: Senior.configuration.open_ai.access_token,
|
49
|
+
organization_id: Senior.configuration.open_ai.organization_id
|
50
50
|
)
|
51
51
|
end
|
52
52
|
|
@@ -55,19 +55,18 @@ module Senior
|
|
55
55
|
# @api private
|
56
56
|
#
|
57
57
|
# @param prompt [String] The prompt for which to generate a completion
|
58
|
-
# @param max_tokens [Integer] The maximum number of tokens to generate in the completion. Default value is 1024
|
59
58
|
#
|
60
59
|
# @return [String] The create completion
|
61
60
|
#
|
62
|
-
def request_completion(prompt
|
61
|
+
def request_completion(prompt)
|
63
62
|
response = open_ai_client.completions(
|
64
63
|
parameters: {
|
65
|
-
model:
|
64
|
+
model: defaults.model,
|
66
65
|
prompt:,
|
67
|
-
max_tokens
|
68
|
-
n:
|
66
|
+
max_tokens: defaults.max_tokens,
|
67
|
+
n: defaults.n,
|
69
68
|
stop: nil,
|
70
|
-
temperature:
|
69
|
+
temperature: defaults.temperature
|
71
70
|
}
|
72
71
|
)
|
73
72
|
|
@@ -75,6 +74,16 @@ module Senior
|
|
75
74
|
|
76
75
|
response.dig('choices', 0, 'text').strip
|
77
76
|
end
|
77
|
+
|
78
|
+
# Returns the default configuration object for the OpenAI brain
|
79
|
+
#
|
80
|
+
# @api private
|
81
|
+
#
|
82
|
+
# @return [Senior::Configuration::OpenAI] The default configuration object for the OpenAI brain.
|
83
|
+
#
|
84
|
+
def defaults
|
85
|
+
Senior.configuration.open_ai
|
86
|
+
end
|
78
87
|
end
|
79
88
|
end
|
80
89
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'senior/configuration/open_ai'
|
4
|
+
|
5
|
+
module Senior
|
6
|
+
module Configuration
|
7
|
+
# Index file for all configurations of the gem
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
#
|
11
|
+
class Main
|
12
|
+
# The OpenAI configuration
|
13
|
+
#
|
14
|
+
# @api public
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# configuration = Senior::Configuration::Main.new
|
19
|
+
# configuration.open_ai # => #<Configuration::OpenAI:0x00007fa2a61a63d8>
|
20
|
+
#
|
21
|
+
# @return [Configuration::OpenAI] The OpenAI configuration
|
22
|
+
#
|
23
|
+
attr_accessor :open_ai
|
24
|
+
|
25
|
+
# Initializes a new instance of the configuration for the Senior gem
|
26
|
+
#
|
27
|
+
# @api public
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# configuration = Senior::Configuration::Main.new
|
31
|
+
#
|
32
|
+
def initialize
|
33
|
+
@open_ai = Configuration::OpenAI.new
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Senior
|
4
|
+
module Configuration
|
5
|
+
# Encapsulates the OpenAI configuration
|
6
|
+
#
|
7
|
+
# @api public
|
8
|
+
class OpenAI
|
9
|
+
# The OpenAI access token
|
10
|
+
#
|
11
|
+
# @return [String, nil] The OpenAI access token, or nil if not set
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# configuration = Senior::Configuration::OpenAI.new
|
15
|
+
# configuration.access_token = 'your_openai_api_key'
|
16
|
+
attr_writer :access_token
|
17
|
+
|
18
|
+
# The OpenAI API version
|
19
|
+
#
|
20
|
+
# @return [String] The OpenAI API version
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# configuration = Senior::Configuration::OpenAI.new
|
24
|
+
# configuration.api_version = 'v1'
|
25
|
+
attr_accessor :api_version
|
26
|
+
|
27
|
+
# The maximum number of tokens to use in the OpenAI API request
|
28
|
+
#
|
29
|
+
# @return [Integer] The maximum number of tokens to use in the OpenAI API request
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# configuration = Senior::Configuration::OpenAI.new
|
33
|
+
# configuration.max_tokens = 1024
|
34
|
+
attr_accessor :max_tokens
|
35
|
+
|
36
|
+
# The OpenAI model to use
|
37
|
+
#
|
38
|
+
# @return [String] The OpenAI model to use
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# configuration = Senior::Configuration::OpenAI.new
|
42
|
+
# configuration.model = 'text-davinci-003'
|
43
|
+
attr_accessor :model
|
44
|
+
|
45
|
+
# The number of responses to generate
|
46
|
+
#
|
47
|
+
# @return [Integer] The number of responses to generate
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# configuration = Senior::Configuration::OpenAI.new
|
51
|
+
# configuration.n = 1
|
52
|
+
attr_accessor :n
|
53
|
+
|
54
|
+
# The OpenAI organization ID
|
55
|
+
#
|
56
|
+
# @return [String, nil] The OpenAI organization ID, or nil if not set
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
# configuration = Senior::Configuration::OpenAI.new
|
60
|
+
# configuration.organization_id = 'your_organization_id'
|
61
|
+
attr_accessor :organization_id
|
62
|
+
|
63
|
+
# The maximum amount of time to wait for an OpenAI API request to complete
|
64
|
+
#
|
65
|
+
# @return [Integer] The maximum amount of time to wait for an OpenAI API request to complete
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# configuration = Senior::Configuration::OpenAI.new
|
69
|
+
# configuration.request_timeout = 120
|
70
|
+
attr_accessor :request_timeout
|
71
|
+
|
72
|
+
# The temperature to use in the OpenAI API request
|
73
|
+
#
|
74
|
+
# @return [Float] The temperature to use in the OpenAI API request
|
75
|
+
#
|
76
|
+
# @example
|
77
|
+
# configuration = Senior::Configuration::OpenAI.new
|
78
|
+
# configuration.temperature = 0.7
|
79
|
+
attr_accessor :temperature
|
80
|
+
|
81
|
+
# The OpenAI URI base
|
82
|
+
#
|
83
|
+
# @return [String] The OpenAI URI base
|
84
|
+
#
|
85
|
+
# @example
|
86
|
+
# configuration = Senior::Configuration::OpenAI.new
|
87
|
+
# configuration.uri_base = 'https://api.openai.com/'
|
88
|
+
attr_accessor :uri_base
|
89
|
+
|
90
|
+
# The default OpenAI API version
|
91
|
+
DEFAULT_API_VERSION = 'v1'
|
92
|
+
|
93
|
+
# The default maximum number of tokens to use in the OpenAI API request
|
94
|
+
DEFAULT_MAX_TOKENS = 1024
|
95
|
+
|
96
|
+
# The default OpenAI model to use
|
97
|
+
DEFAULT_MODEL = 'text-davinci-003'
|
98
|
+
|
99
|
+
# The default number of responses to generate
|
100
|
+
DEFAULT_N = 1
|
101
|
+
|
102
|
+
# The default maximum amount of time to wait for an OpenAI API request to complete
|
103
|
+
DEFAULT_REQUEST_TIMEOUT = 120
|
104
|
+
|
105
|
+
# The default temperature to use in the OpenAI API request
|
106
|
+
DEFAULT_TEMPERATURE = 0.7
|
107
|
+
|
108
|
+
# The default OpenAI URI base
|
109
|
+
DEFAULT_URI_BASE = 'https://api.openai.com/'
|
110
|
+
|
111
|
+
# Initializes a new instance of the OpenAI configuration for the Senior gem
|
112
|
+
#
|
113
|
+
# @example
|
114
|
+
# configuration = Senior::Configuration::OpenAI.new
|
115
|
+
#
|
116
|
+
def initialize
|
117
|
+
@access_token = nil
|
118
|
+
@api_version = DEFAULT_API_VERSION
|
119
|
+
@max_tokens = DEFAULT_MAX_TOKENS
|
120
|
+
@model = DEFAULT_MODEL
|
121
|
+
@n = DEFAULT_N
|
122
|
+
@organization_id = nil
|
123
|
+
@request_timeout = DEFAULT_REQUEST_TIMEOUT
|
124
|
+
@temperature = DEFAULT_TEMPERATURE
|
125
|
+
@uri_base = DEFAULT_URI_BASE
|
126
|
+
end
|
127
|
+
|
128
|
+
# Gets the OpenAI access token, raising an error if it is not set
|
129
|
+
#
|
130
|
+
# @raise [ConfigurationError] If the OpenAI access token is not set
|
131
|
+
#
|
132
|
+
# @return [String] The OpenAI access token.
|
133
|
+
#
|
134
|
+
# @example
|
135
|
+
# configuration = Senior::Configuration::OpenAI.new
|
136
|
+
# configuration.access_token # => raises ConfigurationError if access token is not set
|
137
|
+
#
|
138
|
+
def access_token
|
139
|
+
return @access_token if @access_token
|
140
|
+
|
141
|
+
error_text = 'OpenAI access token missing! See https://github.com/wilsonsilva/senior#usage'
|
142
|
+
raise ConfigurationError, error_text
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
data/lib/senior/version.rb
CHANGED
data/lib/senior.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'senior/errors'
|
4
|
+
require_relative 'senior/configuration/main'
|
3
5
|
require_relative 'senior/brains/open_ai'
|
4
6
|
require_relative 'senior/agent'
|
5
7
|
require_relative 'senior/version'
|
@@ -56,4 +58,32 @@ module Senior
|
|
56
58
|
def self.agent
|
57
59
|
@agent ||= Agent.new
|
58
60
|
end
|
61
|
+
|
62
|
+
# Returns the configuration object for the Senior gem
|
63
|
+
#
|
64
|
+
# @api private
|
65
|
+
#
|
66
|
+
# @return [Senior::Configuration::Main] The configuration object for the Senior gem
|
67
|
+
#
|
68
|
+
def self.configuration
|
69
|
+
@configuration ||= Configuration::Main.new
|
70
|
+
end
|
71
|
+
|
72
|
+
# Provides a way to configure the Senior gem
|
73
|
+
#
|
74
|
+
# @api public
|
75
|
+
#
|
76
|
+
# @yield [configuration] A block to configure the Senior gem
|
77
|
+
# @yieldparam configuration [Senior::Configuration::Main] The configuration object for the Senior gem
|
78
|
+
#
|
79
|
+
# @example Configuring the Senior gem
|
80
|
+
# Senior.configure do |config|
|
81
|
+
# config.open_ai.access_token = 'your_openai_api_key'
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# @return [void]
|
85
|
+
#
|
86
|
+
def self.configure
|
87
|
+
yield(configuration)
|
88
|
+
end
|
59
89
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Senior
|
2
|
+
module Configuration
|
3
|
+
class OpenAI
|
4
|
+
DEFAULT_API_VERSION: String
|
5
|
+
DEFAULT_MAX_TOKENS: Integer
|
6
|
+
DEFAULT_MODEL: String
|
7
|
+
DEFAULT_N: Integer
|
8
|
+
DEFAULT_REQUEST_TIMEOUT: Integer
|
9
|
+
DEFAULT_TEMPERATURE: Float
|
10
|
+
DEFAULT_URI_BASE: String
|
11
|
+
|
12
|
+
attr_writer access_token: String?|nil
|
13
|
+
attr_accessor api_version: String
|
14
|
+
attr_accessor max_tokens: Integer
|
15
|
+
attr_accessor model: String
|
16
|
+
attr_accessor n: Integer
|
17
|
+
attr_accessor organization_id: String?|nil
|
18
|
+
attr_accessor request_timeout: Integer
|
19
|
+
attr_accessor temperature: Float
|
20
|
+
attr_accessor uri_base: String
|
21
|
+
|
22
|
+
def initialize: -> void
|
23
|
+
def access_token: -> String?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/sig/senior.rbs
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Senior
|
2
2
|
VERSION: String
|
3
|
+
self.@configuration: Configuration::Main
|
3
4
|
self.@agent: Agent
|
4
5
|
|
5
6
|
def self.auto_debug: (Method broken_method, untyped args, String? | nil broken_method_source) -> untyped
|
6
|
-
|
7
7
|
def self.suggest_fix: (Method broken_method, untyped args) -> String
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
def self.configuration: -> Configuration::Main
|
9
|
+
def self.configure: -> untyped
|
11
10
|
def self.agent: -> Agent
|
12
11
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: senior
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wilson Silva
|
@@ -361,7 +361,7 @@ dependencies:
|
|
361
361
|
- !ruby/object:Gem::Version
|
362
362
|
version: '0.9'
|
363
363
|
description: |-
|
364
|
-
This gem provides a simple interface to OpenAI's
|
364
|
+
This gem provides a simple interface to OpenAI's GPT API for code repair. Given a piece of broken
|
365
365
|
code, the gem generates a corrected version.
|
366
366
|
email:
|
367
367
|
- wilson.dsigns@gmail.com
|
@@ -387,6 +387,9 @@ files:
|
|
387
387
|
- lib/senior.rb
|
388
388
|
- lib/senior/agent.rb
|
389
389
|
- lib/senior/brains/open_ai.rb
|
390
|
+
- lib/senior/configuration/main.rb
|
391
|
+
- lib/senior/configuration/open_ai.rb
|
392
|
+
- lib/senior/errors.rb
|
390
393
|
- lib/senior/version.rb
|
391
394
|
- sig/gems/method_source/method.rbs
|
392
395
|
- sig/gems/ruby-openai/client.rbs
|
@@ -394,6 +397,9 @@ files:
|
|
394
397
|
- sig/senior/agent.rbs
|
395
398
|
- sig/senior/brains/i_brain.rbs
|
396
399
|
- sig/senior/brains/open_ai.rbs
|
400
|
+
- sig/senior/configuration/main.rbs
|
401
|
+
- sig/senior/configuration/open_ai.rbs
|
402
|
+
- sig/senior/errors.rbs
|
397
403
|
homepage: https://github.com/wilsonsilva/senior
|
398
404
|
licenses:
|
399
405
|
- MIT
|