llm_fixer 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0ad882d017de42f02930ba978b352b1fd1b089095b5de7fdbd6aadebce6e574
4
- data.tar.gz: 9cde3148d984a28e3366a5b837e93a0f919d9d30dfe28cc16e444ea550a07985
3
+ metadata.gz: cb73fbc33ad7bb58e87e339fd4bb0a04df64f38902f5aea2729753d7db090644
4
+ data.tar.gz: db8767bcb98be1c1421e133bbe988e12a77892925eaa24701afc8c59760759e3
5
5
  SHA512:
6
- metadata.gz: db7fe05f51c1cc138e993bae90ca6cbfcd0e3c125309ca82bc302d16e6f4448fe409e4afc82b015c9e8319332abf77aec869f7cbf331218d7c166d2d516b97aa
7
- data.tar.gz: ccc4e7d472cb87840daa4e9db929bab22cfa510649945e94d7f9d09217f6e416de20ae77683962db359296bbb232377a7de0488a4d912ccc4abb3206bfcec58a
6
+ metadata.gz: 61d7ffdc4b0f9f9fd2b916d116c7dab2a8800a3dda4b00c996fc11cbc3084922e58fc9e382cb2bd9c0b78212b4b9a3a3e80f5d26c4e35e025fd68e522b2baf96
7
+ data.tar.gz: acc8fec0fb87c8fe25dd5636827881a6848284277b1c53f625c126348c8bb8a52887b234de04825b3b5a8302da28217b8492a4a5a26a5a080f9719ed4c7525ef
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --format documentation
3
+ --color
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
@@ -11,3 +11,5 @@ gem 'rubocop-rails'
11
11
  gem 'rubocop-rspec'
12
12
  gem 'rubocop-rspec_rails'
13
13
  gem 'rubocop-performance'
14
+ gem 'vcr'
15
+ gem 'webmock'
data/Gemfile.lock CHANGED
@@ -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 のベース URL
33
- - `LLM_MODEL` : 使用する LLM モデル
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
- ### ChatGPT
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
- ### Google Gemini
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
- 静的解析ツールコマンド(例:RuboCop)を実行します:
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
- # Rubocop例
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
- puts "args: #{args.inspect}"
21
- if args.empty?
22
- puts 'Usage: llm_fixer fix COMMAND [ARGS...]'
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: #{args.join(' ')}"
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(args)
40
+ success = fixer.fix_file(command_args, additional_prompt)
29
41
  exit(1) unless success
30
42
  end
31
43
 
@@ -0,0 +1,39 @@
1
+ #!/bin/bash
2
+
3
+ if [ -z "$1" ]; then
4
+ echo "Usage: $0 <version>"
5
+ exit 1
6
+ fi
7
+
8
+ # ~/.gem/credentials
9
+ if [ ! -f ~/.gem/credentials ]; then
10
+ echo "Error: ~/.gem/credentials not found. Please set up your RubyGems credentials."
11
+ exit 1
12
+ fi
13
+
14
+ PROJECT_NAME="llm_fixer"
15
+ GITHUB_REPO="kaibadash/llm_fixer"
16
+ VERSION=$1
17
+ echo "Start bumping version: $VERSION"
18
+
19
+ # Publish
20
+ # Add release branch
21
+ git checkout master
22
+ git checkout -b release/$VERSION
23
+ sed -i '' "s/VERSION = \".*\"/VERSION = \"$VERSION\"/" lib/$PROJECT_NAME/version.rb
24
+ git commit -am "Bump version $VERSION"
25
+
26
+ # Publish to rubygems
27
+ gem build $PROJECT_NAME.gemspec
28
+ bundle install
29
+ gem push $PROJECT_NAME-$VERSION.gem
30
+
31
+ # GitHub release
32
+ git tag $VERSION
33
+ git push --tags
34
+ open https://github.com/$GITHUB_REPO/releases/new
35
+
36
+ # merge to master
37
+ git checkout master
38
+ git merge release/$VERSION
39
+
@@ -3,7 +3,6 @@
3
3
  require "openai"
4
4
  require "open3"
5
5
  require "tempfile"
6
- require "pry"
7
6
  require "erb"
8
7
  require "colorize"
9
8
  require "ostruct"
@@ -23,7 +22,7 @@ module LlmFixer
23
22
  puts "LLM model: #{@model}"
24
23
  end
25
24
 
26
- def fix_file(args)
25
+ def fix_file(args, additional_prompt = nil)
27
26
  command = args.join(" ")
28
27
  output, succeeded = run_command(command)
29
28
  if succeeded
@@ -36,7 +35,7 @@ module LlmFixer
36
35
  return false unless file_path
37
36
 
38
37
  # Request correction from LLM
39
- result = generate_fix(file_path, command, output)
38
+ result = generate_fix(file_path, command, output, additional_prompt)
40
39
  return false unless result
41
40
 
42
41
  File.write(file_path, result)
@@ -68,10 +67,9 @@ module LlmFixer
68
67
  [output, succeeded]
69
68
  end
70
69
 
71
- # rubocop:disable Metrics/MethodLength
72
- def generate_fix(file_path, command, error_output)
70
+ def generate_fix(file_path, command, error_output, additional_prompt = nil)
73
71
  file_content = File.read(file_path)
74
- messages = build_messages(file_path, command, error_output, file_content)
72
+ messages = build_messages(file_path, command, error_output, file_content, additional_prompt)
75
73
  puts messages
76
74
  full_response = ""
77
75
  puts "===== Start generating fix ====="
@@ -88,16 +86,13 @@ module LlmFixer
88
86
 
89
87
  full_response.strip!
90
88
  # remove markdown syntax
91
- if full_response.start_with?("```")
92
- full_response = "#{full_response.split("\n")[1..-2].join("\n")}\n"
93
- end
89
+ full_response = "#{full_response.split("\n")[1..-2].join("\n")}\n" if full_response.start_with?("```")
94
90
  puts full_response
95
91
  puts "===== End generating fix ====="
96
92
  full_response
97
93
  end
98
- # rubocop:enable Metrics/MethodLength
99
94
 
100
- def build_messages(file_path, command, error_output, file_content)
95
+ def build_messages(file_path, command, error_output, file_content, additional_prompt = nil)
101
96
  templates = {
102
97
  system: "fix_prompt_system.erb",
103
98
  user: "fix_prompt_user.erb",
@@ -107,7 +102,9 @@ module LlmFixer
107
102
  b = binding
108
103
  system_template = ERB.new(File.read(File.join(File.dirname(__FILE__),
109
104
  "../templates/#{templates[:system]}")))
110
- messages << { role: "system", content: system_template.result(b) }
105
+ system_content = system_template.result(b)
106
+ system_content += "\n#{additional_prompt}" if additional_prompt
107
+ messages << { role: "system", content: system_content }
111
108
  user_template = ERB.new(File.read(File.join(File.dirname(__FILE__),
112
109
  "../templates/#{templates[:user]}")))
113
110
  messages << { role: "user", content: user_template.result(b) }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LlmFixer
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.3"
5
5
  end
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.1
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 00:00:00.000000000 Z
11
+ date: 2025-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -52,6 +52,76 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-performance
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
55
125
  description: A tool that uses LLM to automatically fix errors detected by static analysis
56
126
  tools (such as RuboCop).
57
127
  email:
@@ -61,6 +131,8 @@ executables:
61
131
  extensions: []
62
132
  extra_rdoc_files: []
63
133
  files:
134
+ - ".rspec"
135
+ - ".rspec_status"
64
136
  - ".rubocop.yml"
65
137
  - Gemfile
66
138
  - Gemfile.lock
@@ -68,11 +140,11 @@ files:
68
140
  - README.md
69
141
  - Rakefile
70
142
  - bin/llm_fixer
143
+ - bump_new_version.sh
71
144
  - lib/llm_fixer/static_analysis_fixer.rb
72
145
  - lib/llm_fixer/version.rb
73
146
  - lib/templates/fix_prompt_system.erb
74
147
  - lib/templates/fix_prompt_user.erb
75
- - sample/sample_spec.rb
76
148
  homepage: https://github.com/kaibadash/llm_fixer
77
149
  licenses:
78
150
  - MIT
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe "基本的な算術演算" do
4
- let!(:result) { 1 + 1 }
5
- describe "足し算" do
6
- it "1 + 1 は 2 になること" do
7
- expect(1 + 1).to eq(result)
8
- end
9
- end
10
- end