aireview 0.3.0 → 2.0.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/CHANGELOG.md +46 -0
- data/README.md +277 -28
- data/config/defaults.yml +47 -0
- data/lib/aireview/candidate_checker.rb +24 -22
- data/lib/aireview/cli.rb +46 -12
- data/lib/aireview/config.rb +65 -180
- data/lib/aireview/config_fallbacks.rb +79 -68
- data/lib/aireview/config_layers.rb +110 -0
- data/lib/aireview/config_limits.rb +10 -35
- data/lib/aireview/config_loader.rb +240 -0
- data/lib/aireview/context_budget.rb +22 -20
- data/lib/aireview/context_builder.rb +18 -17
- data/lib/aireview/diff_fetcher.rb +12 -11
- data/lib/aireview/dry_run_report.rb +33 -8
- data/lib/aireview/errors.rb +8 -0
- data/lib/aireview/gitlab_client.rb +10 -9
- data/lib/aireview/llm_client.rb +113 -0
- data/lib/aireview/llm_failure.rb +36 -19
- data/lib/aireview/llm_router.rb +315 -158
- data/lib/aireview/model_candidate.rb +28 -0
- data/lib/aireview/model_checker.rb +148 -0
- data/lib/aireview/model_pool.rb +224 -0
- data/lib/aireview/model_state.rb +82 -0
- data/lib/aireview/publisher.rb +6 -6
- data/lib/aireview/result_parser.rb +98 -0
- data/lib/aireview/review_marker.rb +16 -28
- data/lib/aireview/review_pipeline.rb +88 -86
- data/lib/aireview/review_renderer.rb +19 -11
- data/lib/aireview/reviewer.rb +37 -109
- data/lib/aireview/stage_chains.rb +113 -0
- data/lib/aireview/stages.rb +7 -0
- data/lib/aireview/utils.rb +29 -0
- data/lib/aireview/version.rb +1 -1
- data/lib/aireview.rb +1 -0
- metadata +19 -3
- data/lib/aireview/result_validation.rb +0 -65
data/lib/aireview/version.rb
CHANGED
data/lib/aireview.rb
CHANGED
|
@@ -16,6 +16,7 @@ require_relative 'aireview/secret_scrubber'
|
|
|
16
16
|
require_relative 'aireview/context_builder'
|
|
17
17
|
require_relative 'aireview/reviewer'
|
|
18
18
|
require_relative 'aireview/review_pipeline'
|
|
19
|
+
require_relative 'aireview/model_checker'
|
|
19
20
|
require_relative 'aireview/gitlab_client'
|
|
20
21
|
require_relative 'aireview/jira_client'
|
|
21
22
|
require_relative 'aireview/review_marker'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: aireview
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Denis Levenko
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: dotenv
|
|
@@ -31,6 +31,9 @@ dependencies:
|
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '2.14'
|
|
34
|
+
- - ">="
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: 2.14.4
|
|
34
37
|
type: :runtime
|
|
35
38
|
prerelease: false
|
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -38,6 +41,9 @@ dependencies:
|
|
|
38
41
|
- - "~>"
|
|
39
42
|
- !ruby/object:Gem::Version
|
|
40
43
|
version: '2.14'
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 2.14.4
|
|
41
47
|
- !ruby/object:Gem::Dependency
|
|
42
48
|
name: ruby_llm
|
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -68,12 +74,15 @@ files:
|
|
|
68
74
|
- README.md
|
|
69
75
|
- bin/aireview
|
|
70
76
|
- config/.aireview.yml.example
|
|
77
|
+
- config/defaults.yml
|
|
71
78
|
- lib/aireview.rb
|
|
72
79
|
- lib/aireview/candidate_checker.rb
|
|
73
80
|
- lib/aireview/cli.rb
|
|
74
81
|
- lib/aireview/config.rb
|
|
75
82
|
- lib/aireview/config_fallbacks.rb
|
|
83
|
+
- lib/aireview/config_layers.rb
|
|
76
84
|
- lib/aireview/config_limits.rb
|
|
85
|
+
- lib/aireview/config_loader.rb
|
|
77
86
|
- lib/aireview/context_budget.rb
|
|
78
87
|
- lib/aireview/context_builder.rb
|
|
79
88
|
- lib/aireview/diff_fetcher.rb
|
|
@@ -81,20 +90,27 @@ files:
|
|
|
81
90
|
- lib/aireview/errors.rb
|
|
82
91
|
- lib/aireview/gitlab_client.rb
|
|
83
92
|
- lib/aireview/jira_client.rb
|
|
93
|
+
- lib/aireview/llm_client.rb
|
|
84
94
|
- lib/aireview/llm_failure.rb
|
|
85
95
|
- lib/aireview/llm_router.rb
|
|
96
|
+
- lib/aireview/model_candidate.rb
|
|
97
|
+
- lib/aireview/model_checker.rb
|
|
98
|
+
- lib/aireview/model_pool.rb
|
|
99
|
+
- lib/aireview/model_state.rb
|
|
86
100
|
- lib/aireview/mr_parser.rb
|
|
87
101
|
- lib/aireview/output_schemas.rb
|
|
88
102
|
- lib/aireview/prompts/critique.txt
|
|
89
103
|
- lib/aireview/prompts/generate.txt
|
|
90
104
|
- lib/aireview/publisher.rb
|
|
91
|
-
- lib/aireview/
|
|
105
|
+
- lib/aireview/result_parser.rb
|
|
92
106
|
- lib/aireview/review_marker.rb
|
|
93
107
|
- lib/aireview/review_pipeline.rb
|
|
94
108
|
- lib/aireview/review_renderer.rb
|
|
95
109
|
- lib/aireview/review_schemas.rb
|
|
96
110
|
- lib/aireview/reviewer.rb
|
|
97
111
|
- lib/aireview/secret_scrubber.rb
|
|
112
|
+
- lib/aireview/stage_chains.rb
|
|
113
|
+
- lib/aireview/stages.rb
|
|
98
114
|
- lib/aireview/utils.rb
|
|
99
115
|
- lib/aireview/version.rb
|
|
100
116
|
homepage: https://github.com/DenisDenis9331/aireview
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Aireview
|
|
4
|
-
# Проверка формы ответов LLM после разбора JSON: кандидаты, вердикты, id.
|
|
5
|
-
# Ошибка формы — SchemaError, пайплайн решает, чинить ли ответ повторным
|
|
6
|
-
# запросом. Ожидает от включающего класса value, normalize_id и
|
|
7
|
-
# normalize_decision.
|
|
8
|
-
module ResultValidation
|
|
9
|
-
class SchemaError < StandardError
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
def validate_generate_result_shape!(parsed)
|
|
15
|
-
valid_shape = parsed.is_a?(Hash) && parsed['candidates'].is_a?(Array)
|
|
16
|
-
raise SchemaError, 'expected an object with summary and candidates array' unless valid_shape
|
|
17
|
-
raise SchemaError, 'each generate candidate must be an object' unless parsed['candidates'].all?(Hash)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def validate_critique_result_shape!(parsed)
|
|
21
|
-
valid_shape = parsed.is_a?(Hash) && parsed['verdicts'].is_a?(Array)
|
|
22
|
-
raise SchemaError, 'expected an object with verdicts array' unless valid_shape
|
|
23
|
-
raise SchemaError, 'each critique verdict must be an object' unless parsed['verdicts'].all?(Hash)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def validate_identifiers!(identifiers, missing_message:, duplicate_prefix:)
|
|
27
|
-
raise SchemaError, missing_message unless identifiers.all?
|
|
28
|
-
|
|
29
|
-
duplicate_ids = identifiers.group_by(&:itself).select { |_, ids| ids.size > 1 }.keys
|
|
30
|
-
return if duplicate_ids.empty?
|
|
31
|
-
|
|
32
|
-
raise SchemaError, "#{duplicate_prefix}: #{duplicate_ids.join(', ')}"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def validate_expected_verdict_ids!(verdict_ids, expected_ids)
|
|
36
|
-
return unless expected_ids
|
|
37
|
-
|
|
38
|
-
unknown_ids = verdict_ids - expected_ids
|
|
39
|
-
missing_ids = expected_ids - verdict_ids
|
|
40
|
-
raise SchemaError, "unknown verdict ids: #{unknown_ids.join(', ')}" unless unknown_ids.empty?
|
|
41
|
-
raise SchemaError, "missing verdict ids: #{missing_ids.join(', ')}" unless missing_ids.empty?
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def validate_verdict!(verdict)
|
|
45
|
-
id = normalize_id(value(verdict, 'id'))
|
|
46
|
-
decision = normalize_decision(value(verdict, 'decision'))
|
|
47
|
-
raise SchemaError, "invalid verdict decision for #{id}" unless %w[keep reject].include?(decision)
|
|
48
|
-
|
|
49
|
-
refinement = value(verdict, 'refinement')
|
|
50
|
-
raise SchemaError, "reject verdict cannot include refinement for #{id}" if invalid_refinement?(verdict, decision)
|
|
51
|
-
return if refinement.nil?
|
|
52
|
-
return if refinement.is_a?(Hash)
|
|
53
|
-
|
|
54
|
-
raise SchemaError, "refinement must be an object for #{id}"
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def invalid_refinement?(verdict, decision)
|
|
58
|
-
refinement_key?(verdict) && decision != 'keep'
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def refinement_key?(verdict)
|
|
62
|
-
verdict.key?('refinement') || verdict.key?(:refinement)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|