Class: Legion::LLM::Router::Ranker
- Inherits:
-
Object
- Object
- Legion::LLM::Router::Ranker
- Includes:
- Legion::Logging::Helper
- Defined in:
- lib/legion/llm/router/ranker.rb
Overview
Soft preference, integer weight/affinity, and rendezvous tie-breaking (§10).
Returns the winning RankedCandidate, or nil when no ready candidate exists.
PRIVATE — no call site outside router.rb may invoke Ranker directly.
Class Method Summary collapse
Instance Method Summary collapse
- #call ⇒ Object
-
#initialize(evaluation_set:, requirements:, settings_snapshot:) ⇒ Ranker
constructor
A new instance of Ranker.
Constructor Details
#initialize(evaluation_set:, requirements:, settings_snapshot:) ⇒ Ranker
Returns a new instance of Ranker.
56 57 58 59 60 |
# File 'lib/legion/llm/router/ranker.rb', line 56 def initialize(evaluation_set:, requirements:, settings_snapshot:) @evaluation_set = evaluation_set @requirements = requirements @settings_snapshot = settings_snapshot end |
Class Method Details
.call(evaluation_set:, requirements:, settings_snapshot:) ⇒ RankedCandidate?
50 51 52 53 54 |
# File 'lib/legion/llm/router/ranker.rb', line 50 def self.call(evaluation_set:, requirements:, settings_snapshot:) new(evaluation_set: evaluation_set, requirements: requirements, settings_snapshot: settings_snapshot).call end |
Instance Method Details
#call ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/legion/llm/router/ranker.rb', line 62 def call # Step 1 (§10): start with ready candidates only. ready = @evaluation_set.ready_candidates return nil if ready.empty? log.debug("[llm][ranker] action=rank ready_count=#{ready.size} " \ "seed=#{@requirements.routing_seed[0, 8]}...") # Two-pass band ordering (preferred != required): pass 1 ranks the in-band # lanes; pass 2 (only when pass 1 is empty) ranks everything else, # band-ignoring. No lane is excluded by the band -- the band is a priority, # not a filter. Only the selected pass is computed, so the ranked log lines # are exactly the lanes eligible for this attempt. in_band, out_of_band = band_partition(ready) log.debug("[llm][ranker] action=preferred_band_partition ready=#{ready.size} " \ "in_band=#{in_band.size} out_of_band=#{out_of_band.size}") # Steps 3–4 (§10.2 + D17): base weight, affinity, effective weight. # Step 5 (§10.3): rendezvous score. # Pass 1 wins if non-empty; otherwise pass 2. Within a pass: greatest # effective_weight bucket -> greatest rendezvous score -> ascending lane_id. ranked = compute_ranked(in_band) if in_band.any? ranked ||= compute_ranked(out_of_band) # Select the winner (greatest effective_weight bucket → greatest rendezvous # score → lexicographically ascending lane_id for cryptographically # improbable score collisions). select_winner(ranked) end |