-
Notifications
You must be signed in to change notification settings - Fork 0
add multi-provider model diversity to adversarial pr review (closes #2) #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
396a34a
8507f71
a868b76
5924d82
6b95900
1b5ec73
ba205d6
0fce72b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,11 +3,11 @@ | |
| module Legion | ||
| module Extensions | ||
| module SwarmGithub | ||
| module Runners | ||
|
Check notice on line 6 in lib/legion/extensions/swarm_github/runners/extension_lifecycle.rb
|
||
| module ExtensionLifecycle | ||
| extend self | ||
|
|
||
| def run_lifecycle(generation:, review:, review_k: nil) | ||
| def run_lifecycle(generation:, review:, review_k: nil, review_models: nil) | ||
| config = github_config | ||
| return { success: false, error: :github_not_enabled } unless config[:enabled] | ||
| return { success: false, error: :target_repo_missing } unless config[:target_repo] | ||
|
|
@@ -32,8 +32,9 @@ | |
| labels: config[:pr_labels]) | ||
|
|
||
| k = review_k || default_review_k | ||
| models = review_models || default_review_models | ||
| review_result = run_adversarial_review(owner: owner, repo: repo, | ||
| pull_number: pr[:pull_number], k: k) | ||
| pull_number: pr[:pull_number], k: k, models: models) | ||
|
|
||
| handle_auto_merge(owner: owner, repo: repo, pull_number: pr[:pull_number], | ||
| config: config, review: review, review_result: review_result) | ||
|
|
@@ -98,13 +99,77 @@ | |
| 1 | ||
| end | ||
|
|
||
| def run_adversarial_review(owner:, repo:, pull_number:, k:) # rubocop:disable Naming/MethodParameterName | ||
| def default_review_models | ||
| return [] unless defined?(Legion::Settings) | ||
|
|
||
| Legion::Settings.dig(:codegen, :self_generate, :github, :review_models) || [] | ||
| rescue StandardError => e | ||
| log.warn(e.message) | ||
| [] | ||
| end | ||
|
|
||
| def provider_available?(provider_sym) | ||
| return false unless defined?(Legion::Settings) | ||
|
|
||
| Legion::Settings.dig(:llm, :providers, provider_sym, :enabled) == true | ||
| rescue StandardError => e | ||
| log.warn(e.message) | ||
| false | ||
| end | ||
|
|
||
| def build_model_assignments(count, models) | ||
| return Array.new(count) { nil } if models.nil? | ||
|
|
||
| unless models.is_a?(Array) | ||
| log.warn("review_models must be an Array, got #{models.class}; using defaults") | ||
| return Array.new(count) { nil } | ||
| end | ||
|
|
||
| return Array.new(count) { nil } if models.empty? | ||
|
|
||
| available = models.filter_map do |raw_spec| | ||
| unless raw_spec.is_a?(Hash) | ||
| log.warn('review model spec is not a Hash, skipping') | ||
| next | ||
| end | ||
|
|
||
| spec = raw_spec.transform_keys { |k| k.respond_to?(:to_sym) ? k.to_sym : k } | ||
| provider_value = spec[:provider] | ||
|
|
||
| if provider_value && !provider_value.respond_to?(:to_sym) | ||
| log.warn("review provider value #{provider_value.inspect} (#{provider_value.class}) cannot be symbolized, skipping") | ||
| next | ||
| end | ||
|
|
||
| provider_sym = provider_value&.to_sym | ||
| spec[:provider] = provider_sym if provider_sym | ||
|
|
||
| if provider_sym && !provider_available?(provider_sym) | ||
| log.warn("review provider #{provider_sym} not available, skipping") | ||
|
Esity marked this conversation as resolved.
|
||
| next | ||
| end | ||
|
|
||
| spec | ||
| end | ||
|
|
||
| return Array.new(count) { nil } if available.empty? | ||
|
|
||
| assignments = available.first(count) | ||
| assignments + Array.new([count - assignments.length, 0].max) { nil } | ||
|
Esity marked this conversation as resolved.
|
||
| end | ||
|
Comment on lines
+157
to
+159
|
||
|
|
||
| def run_adversarial_review(owner:, repo:, pull_number:, k:, models: []) # rubocop:disable Naming/MethodParameterName | ||
| return { success: true, skipped: true, reason: :reviewer_unavailable } unless pr_reviewer_available? | ||
|
|
||
| reviews = Array.new(k) do | ||
| Legion::Extensions::SwarmGithub::Runners::PullRequestReviewer.review_pull_request( | ||
| owner: owner, repo: repo, pull_number: pull_number | ||
| ) | ||
| assignments = build_model_assignments(k, models) | ||
|
|
||
| reviews = assignments.map do |spec| | ||
| kwargs = { owner: owner, repo: repo, pull_number: pull_number } | ||
| if spec | ||
| kwargs[:model] = spec[:model] if spec[:model] | ||
| kwargs[:provider] = spec[:provider] if spec[:provider] | ||
| end | ||
| Legion::Extensions::SwarmGithub::Runners::PullRequestReviewer.review_pull_request(**kwargs) | ||
| end | ||
|
Esity marked this conversation as resolved.
|
||
|
|
||
| approvals = reviews.count do |r| | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,7 +3,7 @@ | |
| module Legion | ||
| module Extensions | ||
| module SwarmGithub | ||
| VERSION = '0.3.1' | ||
| VERSION = '0.3.2' | ||
| end | ||
| end | ||
| end | ||
Uh oh!
There was an error while loading. Please reload this page.