Module: Legion::LLM::Router
- Extended by:
- Legion::Logging::Helper
- Defined in:
- lib/legion/llm/router.rb,
lib/legion/llm/router/rule.rb,
lib/legion/llm/router/arbitrage.rb,
lib/legion/llm/router/resolution.rb,
lib/legion/llm/router/health_tracker.rb,
lib/legion/llm/router/escalation/chain.rb,
lib/legion/llm/router/gateway_interceptor.rb
Defined Under Namespace
Modules: Arbitrage, GatewayInterceptor
Classes: EscalationChain, HealthTracker, Resolution, Rule
Constant Summary
collapse
- PROVIDER_TIER =
{ bedrock: :cloud, anthropic: :frontier, openai: :frontier,
gemini: :cloud, azure: :cloud, ollama: :local, vllm: :fleet }.freeze
- PROVIDER_ORDER =
%i[ollama vllm bedrock azure gemini anthropic openai].freeze
- TIER_EXTERNAL =
Set[:cloud, :frontier, :openai_compat].freeze
- OLLAMA_MODEL_PATTERN =
%r{[:/]}
Class Method Summary
collapse
Class Method Details
.auto_rules_populated? ⇒ Boolean
90
91
92
|
# File 'lib/legion/llm/router.rb', line 90
def auto_rules_populated?
@auto_rules_populated == true
end
|
.health_tracker ⇒ Object
79
80
81
|
# File 'lib/legion/llm/router.rb', line 79
def health_tracker
@health_tracker ||= build_health_tracker
end
|
.infer_provider_for_model(model) ⇒ Object
29
30
31
32
33
34
35
36
37
38
39
40
|
# File 'lib/legion/llm/router.rb', line 29
def infer_provider_for_model(model)
return nil if model.nil? || model.to_s.empty?
model_s = model.to_s
return :bedrock if model_s.start_with?('us.')
return :openai if model_s.match?(/\Agpt-|\Ao[134]-/)
return :anthropic if model_s.start_with?('claude-')
return :gemini if model_s.start_with?('gemini-')
return :ollama if model_s.match?(OLLAMA_MODEL_PATTERN)
nil
end
|
.populate_auto_rules(discovered_instances) ⇒ Object
94
95
96
97
98
99
|
# File 'lib/legion/llm/router.rb', line 94
def populate_auto_rules(discovered_instances)
raw = Discovery::RuleGenerator.generate(discovered_instances)
@auto_rules = raw.map { |h| Rule.from_hash(h.transform_keys(&:to_sym)) }
@auto_rules_populated = true
log.info("[llm][router] auto_rules_populated count=#{@auto_rules.size}")
end
|
.reset! ⇒ Object
101
102
103
104
105
|
# File 'lib/legion/llm/router.rb', line 101
def reset!
@health_tracker = nil
@auto_rules = []
@auto_rules_populated = false
end
|
.resolve(intent: nil, tier: nil, model: nil, provider: nil, exclude: {}) ⇒ Resolution?
Resolve an LLM routing intent to a tier/provider/model decision.
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
# File 'lib/legion/llm/router.rb', line 49
def resolve(intent: nil, tier: nil, model: nil, provider: nil, exclude: {})
log.debug "[llm][router] action=resolve.enter intent=#{intent} tier=#{tier} model=#{model} provider=#{provider}"
return explicit_resolution(tier, provider, model) if tier
return nil unless routing_enabled? && intent
merged = merge_defaults(intent)
rules = load_rules
candidates = select_candidates(rules, merged, exclude: exclude)
best = pick_best(candidates)
resolution = best&.to_resolution
if resolution
log.info("Routed to tier=#{resolution.tier} provider=#{resolution.provider} model=#{resolution.model} via rule='#{resolution.rule}'")
else
log.debug('Router: no rules matched, resolution is nil')
end
resolution || arbitrage_fallback(intent)
end
|
.resolve_chain(intent: nil, tier: nil, model: nil, provider: nil, max_escalations: nil, exclude: {}) ⇒ Object
70
71
72
73
74
75
76
77
|
# File 'lib/legion/llm/router.rb', line 70
def resolve_chain(intent: nil, tier: nil, model: nil, provider: nil, max_escalations: nil, exclude: {})
log.debug "[llm][router] action=resolve_chain.enter intent=#{intent} tier=#{tier} max_escalations=#{max_escalations}"
max = max_escalations || escalation_max_attempts
return EscalationChain.new(resolutions: [explicit_resolution(tier, provider, model)], max_attempts: max) if tier
return chain_from_defaults(model, provider, max) unless routing_enabled? && intent
chain_from_intent(intent, max, exclude: exclude)
end
|
.routing_enabled? ⇒ Boolean
83
84
85
86
87
88
|
# File 'lib/legion/llm/router.rb', line 83
def routing_enabled?
settings = routing_settings
return false if settings.nil? || settings.empty?
settings[:enabled] == true && auto_rules_populated?
end
|
.tier_available?(tier) ⇒ Boolean
Check whether a tier can be used right now. :local — always available :direct — always available (remote self-hosted instances) :fleet — available when Legion::Transport is loaded :openai_compat — available when gateways are configured :cloud — available unless privacy mode :frontier — available unless privacy mode
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/legion/llm/router.rb', line 114
def tier_available?(tier)
sym = tier.to_sym
if external_tier?(sym) && privacy_mode?
log.debug "[llm][router] action=tier_available tier=#{sym} available=false reason=privacy_mode"
return false
end
if sym == :fleet
available = Legion.const_defined?('Transport', false)
log.debug "[llm][router] action=tier_available tier=fleet available=#{available}"
return available
end
if sym == :openai_compat
available = openai_compat_available?
log.debug "[llm][router] action=tier_available tier=openai_compat available=#{available}"
return available
end
true
end
|