llm_fixer 0.0.2 → 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/.rspec +3 -0
- data/.rspec_status +12 -0
- data/.rubocop.yml +10 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +17 -1
- data/README.md +32 -17
- data/bin/llm_fixer +20 -8
- data/lib/llm_fixer/static_analysis_fixer.rb +9 -9
- data/lib/llm_fixer/version.rb +1 -1
- metadata +4 -3
- data/sample/sample_spec.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb73fbc33ad7bb58e87e339fd4bb0a04df64f38902f5aea2729753d7db090644
|
4
|
+
data.tar.gz: db8767bcb98be1c1421e133bbe988e12a77892925eaa24701afc8c59760759e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61d7ffdc4b0f9f9fd2b916d116c7dab2a8800a3dda4b00c996fc11cbc3084922e58fc9e382cb2bd9c0b78212b4b9a3a3e80f5d26c4e35e025fd68e522b2baf96
|
7
|
+
data.tar.gz: acc8fec0fb87c8fe25dd5636827881a6848284277b1c53f625c126348c8bb8a52887b234de04825b3b5a8302da28217b8492a4a5a26a5a080f9719ed4c7525ef
|
data/.rspec
ADDED
data/.rspec_status
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
example_id | status | run_time |
|
2
|
+
------------------------------------------------------- | ------ | --------------- |
|
3
|
+
./spec/llm_fixer/static_analysis_fixer_spec.rb[1:1:1:1] | passed | 0.01216 seconds |
|
4
|
+
./spec/llm_fixer/static_analysis_fixer_spec.rb[1:1:2:1] | passed | 0.0065 seconds |
|
5
|
+
./spec/llm_fixer/static_analysis_fixer_spec.rb[1:1:2:2] | passed | 0.00644 seconds |
|
6
|
+
./spec/llm_fixer/static_analysis_fixer_spec.rb[1:1:3:1] | passed | 0.00635 seconds |
|
7
|
+
./spec/llm_fixer/static_analysis_fixer_spec.rb[1:2:1] | passed | 0.00056 seconds |
|
8
|
+
./spec/llm_fixer/static_analysis_fixer_spec.rb[1:2:2] | passed | 0.00033 seconds |
|
9
|
+
./spec/llm_fixer/static_analysis_fixer_spec.rb[1:3:1] | passed | 0.00156 seconds |
|
10
|
+
./spec/llm_fixer/static_analysis_fixer_spec.rb[1:3:2] | passed | 0.00018 seconds |
|
11
|
+
./spec/llm_fixer/static_analysis_fixer_spec.rb[1:4:1:1] | passed | 0.00012 seconds |
|
12
|
+
./spec/llm_fixer/static_analysis_fixer_spec.rb[1:4:2:1] | passed | 0.00015 seconds |
|
data/.rubocop.yml
CHANGED
@@ -19,8 +19,18 @@ AllCops:
|
|
19
19
|
- "config/**/*"
|
20
20
|
- "db/**/*"
|
21
21
|
- "deploy/**/*"
|
22
|
+
- "llm_fixer.gemspec"
|
22
23
|
NewCops: enable
|
23
24
|
|
24
25
|
Rails/Output:
|
25
26
|
Enabled: false
|
26
27
|
AutoCorrect: false
|
28
|
+
|
29
|
+
Rails/Exit:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Metrics/BlockLength:
|
33
|
+
Max: 150
|
34
|
+
|
35
|
+
Layout/LineLength:
|
36
|
+
Max: 125
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
llm_fixer (0.0.
|
4
|
+
llm_fixer (0.0.1)
|
5
5
|
colorize
|
6
6
|
ruby-openai
|
7
7
|
thor
|
@@ -22,6 +22,8 @@ GEM
|
|
22
22
|
securerandom (>= 0.3)
|
23
23
|
tzinfo (~> 2.0, >= 2.0.5)
|
24
24
|
uri (>= 0.13.1)
|
25
|
+
addressable (2.8.7)
|
26
|
+
public_suffix (>= 2.0.2, < 7.0)
|
25
27
|
ast (2.4.2)
|
26
28
|
base64 (0.2.0)
|
27
29
|
benchmark (0.4.0)
|
@@ -31,6 +33,9 @@ GEM
|
|
31
33
|
colorize (1.1.0)
|
32
34
|
concurrent-ruby (1.3.5)
|
33
35
|
connection_pool (2.5.0)
|
36
|
+
crack (1.0.0)
|
37
|
+
bigdecimal
|
38
|
+
rexml
|
34
39
|
diff-lcs (1.6.0)
|
35
40
|
drb (2.2.1)
|
36
41
|
event_stream_parser (1.0.0)
|
@@ -42,6 +47,7 @@ GEM
|
|
42
47
|
multipart-post (~> 2.0)
|
43
48
|
faraday-net_http (3.4.0)
|
44
49
|
net-http (>= 0.5.0)
|
50
|
+
hashdiff (1.1.2)
|
45
51
|
i18n (1.14.7)
|
46
52
|
concurrent-ruby (~> 1.0)
|
47
53
|
json (2.9.1)
|
@@ -62,10 +68,12 @@ GEM
|
|
62
68
|
pry-byebug (3.10.1)
|
63
69
|
byebug (~> 11.0)
|
64
70
|
pry (>= 0.13, < 0.15)
|
71
|
+
public_suffix (6.0.1)
|
65
72
|
racc (1.8.1)
|
66
73
|
rack (3.1.11)
|
67
74
|
rainbow (3.1.1)
|
68
75
|
regexp_parser (2.10.0)
|
76
|
+
rexml (3.4.1)
|
69
77
|
rspec (3.13.0)
|
70
78
|
rspec-core (~> 3.13.0)
|
71
79
|
rspec-expectations (~> 3.13.0)
|
@@ -117,6 +125,12 @@ GEM
|
|
117
125
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
118
126
|
unicode-emoji (4.0.4)
|
119
127
|
uri (1.0.3)
|
128
|
+
vcr (6.3.1)
|
129
|
+
base64
|
130
|
+
webmock (3.25.1)
|
131
|
+
addressable (>= 2.8.0)
|
132
|
+
crack (>= 0.3.2)
|
133
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
120
134
|
|
121
135
|
PLATFORMS
|
122
136
|
arm64-darwin-23
|
@@ -132,6 +146,8 @@ DEPENDENCIES
|
|
132
146
|
rubocop-rails
|
133
147
|
rubocop-rspec
|
134
148
|
rubocop-rspec_rails
|
149
|
+
vcr
|
150
|
+
webmock
|
135
151
|
|
136
152
|
BUNDLED WITH
|
137
153
|
2.6.2
|
data/README.md
CHANGED
@@ -2,41 +2,41 @@
|
|
2
2
|
|
3
3
|
# LLM fixer
|
4
4
|
|
5
|
-
|
5
|
+
A tool that automatically fixes static analysis errors.
|
6
6
|
|
7
|
-
##
|
7
|
+
## Installation
|
8
8
|
|
9
|
-
Gemfile
|
9
|
+
Add this line to your Gemfile:
|
10
10
|
|
11
11
|
```ruby
|
12
12
|
gem 'llm_fixer'
|
13
13
|
```
|
14
14
|
|
15
|
-
|
15
|
+
And then execute:
|
16
16
|
|
17
17
|
```bash
|
18
18
|
$ bundle install
|
19
19
|
```
|
20
20
|
|
21
|
-
|
21
|
+
Or install it yourself as:
|
22
22
|
|
23
23
|
```bash
|
24
24
|
$ gem install llm_fixer
|
25
25
|
```
|
26
26
|
|
27
|
-
##
|
27
|
+
## Environment Variables
|
28
28
|
|
29
|
-
|
29
|
+
You can customize the behavior using the following environment variables:
|
30
30
|
|
31
|
-
- `LLM_API_KEY` : LLM API
|
32
|
-
- `LLM_API_BASE` : LLM API
|
33
|
-
- `LLM_MODEL` :
|
31
|
+
- `LLM_API_KEY` : LLM API key
|
32
|
+
- `LLM_API_BASE` : Base URL for the LLM API
|
33
|
+
- `LLM_MODEL` : LLM model to use
|
34
34
|
|
35
|
-
##
|
35
|
+
## Usage
|
36
36
|
|
37
|
-
|
37
|
+
Set the environment variables:
|
38
38
|
|
39
|
-
|
39
|
+
ChatGPT
|
40
40
|
|
41
41
|
```bash
|
42
42
|
export LLM_API_KEY="your-api-key-here"
|
@@ -44,7 +44,7 @@ export LLM_API_BASE="https://api.openai.com/v1"
|
|
44
44
|
export LLM_MODEL="gpt-4o"
|
45
45
|
```
|
46
46
|
|
47
|
-
|
47
|
+
Google Gemini
|
48
48
|
|
49
49
|
```bash
|
50
50
|
export LLM_API_KEY="your-api-key-here"
|
@@ -52,13 +52,28 @@ export LLM_API_BASE="https://generativelanguage.googleapis.com/v1beta"
|
|
52
52
|
export LLM_MODEL="gemini-2.0-pro-exp"
|
53
53
|
```
|
54
54
|
|
55
|
-
|
55
|
+
Local(LM Studio)
|
56
56
|
|
57
|
-
|
57
|
+
```bash
|
58
|
+
export LLM_API_KEY="n/a"
|
59
|
+
export LLM_API_BASE="http://localhost:1234"
|
60
|
+
export LLM_MODEL="tinyswallow-1.5b-instruct"
|
61
|
+
```
|
62
|
+
|
63
|
+
##
|
64
|
+
|
65
|
+
Run your static analysis tool command (e.g., RuboCop):
|
58
66
|
|
59
67
|
```bash
|
60
68
|
llm_fixer fix your-lint-or-test-command path/to/target
|
61
69
|
|
62
|
-
#
|
70
|
+
# RuboCop example
|
63
71
|
llm_fixer fix bundle exec rubocop path/to/target.rb
|
72
|
+
|
73
|
+
# With additional prompt to guide the LLM
|
74
|
+
llm_fixer fix --additional-prompt "Follow the style guide and use double quotes" bundle exec rubocop path/to/target.rb
|
75
|
+
# or using the short form
|
76
|
+
llm_fixer fix -a "Follow the style guide and use double quotes" bundle exec rubocop path/to/target.rb
|
64
77
|
```
|
78
|
+
|
79
|
+
The `--additional-prompt` (or `-a`) option allows you to provide additional instructions to the LLM when fixing errors. This can be useful when you want to customize the style or approach used for fixes.
|
data/bin/llm_fixer
CHANGED
@@ -5,8 +5,7 @@ require 'thor'
|
|
5
5
|
require_relative '../lib/llm_fixer/static_analysis_fixer'
|
6
6
|
|
7
7
|
class CLI < Thor
|
8
|
-
desc 'fix COMMAND [ARGS...]', 'Static analysis errors are automatically fixed by LLM'
|
9
|
-
method_option :command, type: :string, required: false
|
8
|
+
desc 'fix [--additional-prompt TEXT | -a TEXT] COMMAND [ARGS...]', 'Static analysis errors are automatically fixed by LLM'
|
10
9
|
|
11
10
|
def fix(*args)
|
12
11
|
%w[LLM_API_BASE LLM_MODEL LLM_API_KEY].each do |key|
|
@@ -16,16 +15,29 @@ class CLI < Thor
|
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
additional_prompt = nil
|
19
|
+
command_args = args.dup
|
20
|
+
|
21
|
+
if command_args[0] == '--additional-prompt' || command_args[0] == '-a'
|
22
|
+
command_args.shift
|
23
|
+
additional_prompt = command_args.shift
|
24
|
+
if additional_prompt.nil? || additional_prompt.empty?
|
25
|
+
puts 'ERROR: Additional prompt option requires a value'
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
puts "args: #{command_args.inspect}"
|
31
|
+
if command_args.empty?
|
32
|
+
puts 'Usage: llm_fixer fix [--additional-prompt TEXT | -a TEXT] COMMAND [ARGS...]'
|
23
33
|
exit 1
|
24
34
|
end
|
25
35
|
|
26
|
-
puts "command: #{
|
36
|
+
puts "command: #{command_args.join(' ')}"
|
37
|
+
puts "additional prompt: #{additional_prompt}" if additional_prompt
|
38
|
+
|
27
39
|
fixer = LlmFixer::StaticAnalysisFixer.new(ENV.fetch('LLM_API_KEY', nil))
|
28
|
-
success = fixer.fix_file(
|
40
|
+
success = fixer.fix_file(command_args, additional_prompt)
|
29
41
|
exit(1) unless success
|
30
42
|
end
|
31
43
|
|
@@ -22,7 +22,7 @@ module LlmFixer
|
|
22
22
|
puts "LLM model: #{@model}"
|
23
23
|
end
|
24
24
|
|
25
|
-
def fix_file(args)
|
25
|
+
def fix_file(args, additional_prompt = nil)
|
26
26
|
command = args.join(" ")
|
27
27
|
output, succeeded = run_command(command)
|
28
28
|
if succeeded
|
@@ -35,7 +35,7 @@ module LlmFixer
|
|
35
35
|
return false unless file_path
|
36
36
|
|
37
37
|
# Request correction from LLM
|
38
|
-
result = generate_fix(file_path, command, output)
|
38
|
+
result = generate_fix(file_path, command, output, additional_prompt)
|
39
39
|
return false unless result
|
40
40
|
|
41
41
|
File.write(file_path, result)
|
@@ -67,9 +67,9 @@ module LlmFixer
|
|
67
67
|
[output, succeeded]
|
68
68
|
end
|
69
69
|
|
70
|
-
def generate_fix(file_path, command, error_output)
|
70
|
+
def generate_fix(file_path, command, error_output, additional_prompt = nil)
|
71
71
|
file_content = File.read(file_path)
|
72
|
-
messages = build_messages(file_path, command, error_output, file_content)
|
72
|
+
messages = build_messages(file_path, command, error_output, file_content, additional_prompt)
|
73
73
|
puts messages
|
74
74
|
full_response = ""
|
75
75
|
puts "===== Start generating fix ====="
|
@@ -86,15 +86,13 @@ module LlmFixer
|
|
86
86
|
|
87
87
|
full_response.strip!
|
88
88
|
# remove markdown syntax
|
89
|
-
if full_response.start_with?("```")
|
90
|
-
full_response = "#{full_response.split("\n")[1..-2].join("\n")}\n"
|
91
|
-
end
|
89
|
+
full_response = "#{full_response.split("\n")[1..-2].join("\n")}\n" if full_response.start_with?("```")
|
92
90
|
puts full_response
|
93
91
|
puts "===== End generating fix ====="
|
94
92
|
full_response
|
95
93
|
end
|
96
94
|
|
97
|
-
def build_messages(file_path, command, error_output, file_content)
|
95
|
+
def build_messages(file_path, command, error_output, file_content, additional_prompt = nil)
|
98
96
|
templates = {
|
99
97
|
system: "fix_prompt_system.erb",
|
100
98
|
user: "fix_prompt_user.erb",
|
@@ -104,7 +102,9 @@ module LlmFixer
|
|
104
102
|
b = binding
|
105
103
|
system_template = ERB.new(File.read(File.join(File.dirname(__FILE__),
|
106
104
|
"../templates/#{templates[:system]}")))
|
107
|
-
|
105
|
+
system_content = system_template.result(b)
|
106
|
+
system_content += "\n#{additional_prompt}" if additional_prompt
|
107
|
+
messages << { role: "system", content: system_content }
|
108
108
|
user_template = ERB.new(File.read(File.join(File.dirname(__FILE__),
|
109
109
|
"../templates/#{templates[:user]}")))
|
110
110
|
messages << { role: "user", content: user_template.result(b) }
|
data/lib/llm_fixer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: llm_fixer
|
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
|
- kaiba
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -131,6 +131,8 @@ executables:
|
|
131
131
|
extensions: []
|
132
132
|
extra_rdoc_files: []
|
133
133
|
files:
|
134
|
+
- ".rspec"
|
135
|
+
- ".rspec_status"
|
134
136
|
- ".rubocop.yml"
|
135
137
|
- Gemfile
|
136
138
|
- Gemfile.lock
|
@@ -143,7 +145,6 @@ files:
|
|
143
145
|
- lib/llm_fixer/version.rb
|
144
146
|
- lib/templates/fix_prompt_system.erb
|
145
147
|
- lib/templates/fix_prompt_user.erb
|
146
|
-
- sample/sample_spec.rb
|
147
148
|
homepage: https://github.com/kaibadash/llm_fixer
|
148
149
|
licenses:
|
149
150
|
- MIT
|