legion-llm 0.8.27 → 0.8.28
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 +9 -0
- data/lib/legion/llm/inference/executor.rb +5 -1
- data/lib/legion/llm/inference.rb +2 -1
- data/lib/legion/llm/router.rb +20 -11
- data/lib/legion/llm/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 523afac32d76644a92db4f6af5228c9ff9856521ccffb7cff0a0e8194570a432
|
|
4
|
+
data.tar.gz: b58073ec104d42eb18436fd708a33bea881931386dfab1e578f0570d891a6f55
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 205d3a1ef6f1c9e8712bc61e2d88382b88a91560343ab6be7e5c863f2b839ea3d384f5a5642240f7a62fed73ed96aff7b653855c15c1cb5517a43d342306a54b
|
|
7
|
+
data.tar.gz: 8847c3be8580a5c1c62bd61b83c72ef53db974b19a8567fd102827b748e9113bfc3dc0af7aa14e23d25b524453b2465dd8053e55f64ee2798f9ae9b387cac264
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Legion LLM Changelog
|
|
2
2
|
|
|
3
|
+
## [0.8.28] - 2026-04-24
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Model/provider mismatch when clients send a model name (e.g., `qwen3.5:latest`) without an explicit provider. The fallback paths blindly paired it with `default_provider` (typically `bedrock`), causing `RubyLLM::ModelNotFoundError`. Now infers the correct provider from model naming patterns before falling back to the global default.
|
|
7
|
+
- `arbitrage_fallback` hardcoded `:cloud` tier and `:bedrock` provider when inference failed. Now uses `PROVIDER_TIER` to resolve the correct tier for the inferred provider.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- `Router.infer_provider_for_model(model)` — public method that maps model naming patterns to providers. Recognizes Ollama-style models (`:` or `/` in name), Bedrock (`us.*`), OpenAI (`gpt-*`, `o1-*`/`o3-*`/`o4-*`), Anthropic (`claude-*`), and Gemini (`gemini-*`).
|
|
11
|
+
|
|
3
12
|
## [0.8.27] - 2026-04-24
|
|
4
13
|
|
|
5
14
|
### Fixed
|
|
@@ -328,7 +328,9 @@ module Legion
|
|
|
328
328
|
end
|
|
329
329
|
end
|
|
330
330
|
|
|
331
|
-
@resolved_provider = provider ||
|
|
331
|
+
@resolved_provider = provider ||
|
|
332
|
+
(model && Router.infer_provider_for_model(model)) ||
|
|
333
|
+
Legion::LLM.settings[:default_provider]
|
|
332
334
|
@resolved_model = model || Legion::LLM.settings[:default_model]
|
|
333
335
|
|
|
334
336
|
log.info "[llm][inference] resolved provider=#{@resolved_provider} model=#{@resolved_model}"
|
|
@@ -846,6 +848,8 @@ module Legion
|
|
|
846
848
|
duration_ms = started_at ? ((finished_at - started_at) * 1000).round : nil
|
|
847
849
|
|
|
848
850
|
result_str = (raw.is_a?(String) ? raw : raw.to_s)
|
|
851
|
+
result_str = result_str.encode('UTF-8', invalid: :replace, undef: :replace, replace: '�') unless result_str.valid_encoding?
|
|
852
|
+
result_str = result_str.delete("\x00")
|
|
849
853
|
is_error = raw.is_a?(Hash) && (raw[:error] || raw['error']) ? true : false
|
|
850
854
|
|
|
851
855
|
@pending_tool_history_mutex.synchronize do
|
data/lib/legion/llm/inference.rb
CHANGED
|
@@ -496,7 +496,8 @@ module Legion
|
|
|
496
496
|
end
|
|
497
497
|
|
|
498
498
|
model ||= Legion::LLM.settings[:default_model]
|
|
499
|
-
provider ||=
|
|
499
|
+
provider ||= (model && Router.infer_provider_for_model(model)) ||
|
|
500
|
+
Legion::LLM.settings[:default_provider]
|
|
500
501
|
|
|
501
502
|
opts = {}
|
|
502
503
|
opts[:model] = model if model
|
data/lib/legion/llm/router.rb
CHANGED
|
@@ -18,7 +18,22 @@ module Legion
|
|
|
18
18
|
gemini: :cloud, azure: :cloud, ollama: :local, vllm: :local }.freeze
|
|
19
19
|
PROVIDER_ORDER = %i[ollama vllm bedrock azure gemini anthropic openai].freeze
|
|
20
20
|
|
|
21
|
+
OLLAMA_MODEL_PATTERN = %r{[:/]}
|
|
22
|
+
|
|
21
23
|
class << self
|
|
24
|
+
def infer_provider_for_model(model)
|
|
25
|
+
return nil if model.nil? || model.to_s.empty?
|
|
26
|
+
|
|
27
|
+
model_s = model.to_s
|
|
28
|
+
return :bedrock if model_s.start_with?('us.')
|
|
29
|
+
return :openai if model_s.match?(/\Agpt-|\Ao[134]-/)
|
|
30
|
+
return :anthropic if model_s.start_with?('claude-')
|
|
31
|
+
return :gemini if model_s.start_with?('gemini-')
|
|
32
|
+
return :ollama if model_s.match?(OLLAMA_MODEL_PATTERN)
|
|
33
|
+
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
|
|
22
37
|
# Resolve an LLM routing intent to a tier/provider/model decision.
|
|
23
38
|
#
|
|
24
39
|
# @param intent [Hash, nil] routing intent (capability, privacy, etc.)
|
|
@@ -95,18 +110,12 @@ module Legion
|
|
|
95
110
|
model = Arbitrage.cheapest_for(capability: capability)
|
|
96
111
|
return nil unless model
|
|
97
112
|
|
|
98
|
-
provider =
|
|
99
|
-
|
|
100
|
-
Resolution.new(tier: :cloud, provider: provider || :bedrock, model: model, rule: 'arbitrage_fallback')
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def infer_provider(model)
|
|
104
|
-
return :ollama if model.include?('llama')
|
|
105
|
-
return :bedrock if model.start_with?('us.')
|
|
106
|
-
return :openai if model.start_with?('gpt')
|
|
107
|
-
return :google if model.start_with?('gemini')
|
|
113
|
+
provider = infer_provider_for_model(model)
|
|
114
|
+
return nil unless provider
|
|
108
115
|
|
|
109
|
-
|
|
116
|
+
tier = PROVIDER_TIER.fetch(provider, :cloud)
|
|
117
|
+
log.debug("Router: arbitrage fallback selected model=#{model} provider=#{provider} tier=#{tier}")
|
|
118
|
+
Resolution.new(tier: tier, provider: provider, model: model, rule: 'arbitrage_fallback')
|
|
110
119
|
end
|
|
111
120
|
|
|
112
121
|
def explicit_resolution(tier, provider, model)
|
data/lib/legion/llm/version.rb
CHANGED