legion-llm 0.9.29 → 0.9.30
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 +5 -0
- data/lib/legion/llm/api/anthropic/messages.rb +1 -1
- data/lib/legion/llm/api/native/inference.rb +5 -1
- data/lib/legion/llm/api/openai/chat_completions.rb +1 -1
- data/lib/legion/llm/inference/executor.rb +25 -0
- 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: 221d8482faa90a3fa8e4bbefe90999838a56b96bc34d6506956f6b8ac90ab290
|
|
4
|
+
data.tar.gz: a3c3ce4cde046e8cd1af18874e04da1698d4527549fc70df274d14c0830f3803
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fd2fdd7bce06cd6efa9a8b583072b947f14ffdaa5a1898b65f2027da8693c79bdd56b3553d04f6f6329f2f3a9d71c0699947f371aa5715708fd538a144819363
|
|
7
|
+
data.tar.gz: 7c3c36ca8b7db0075b18ea656e3c13c9235d873362d8febbe663c96eb07a1fa562a16d754f1bfed42d909698b466c303d7395e79caa0093ad1d1008c64389f69
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Legion LLM Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.30] - 2026-05-16
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Tools: API-submitted client tools are no longer advertised to providers unless callers explicitly opt into client-tool passthrough, preventing incomplete tool calls from ending streaming responses.
|
|
7
|
+
|
|
3
8
|
## [0.9.29] - 2026-05-16
|
|
4
9
|
|
|
5
10
|
### Added
|
|
@@ -149,7 +149,7 @@ module Legion
|
|
|
149
149
|
name: tname,
|
|
150
150
|
description: tdesc,
|
|
151
151
|
parameters: tschema,
|
|
152
|
-
source: { type: :client, executable:
|
|
152
|
+
source: { type: :client, executable: true }
|
|
153
153
|
)
|
|
154
154
|
rescue StandardError => e
|
|
155
155
|
log.warn("[llm][api][anthropic][messages] build_tool_classes failed name=#{tname} error=#{e.message}")
|
|
@@ -28,6 +28,7 @@ module Legion
|
|
|
28
28
|
conversation_id = body[:conversation_id]
|
|
29
29
|
request_id = body[:request_id] || SecureRandom.uuid
|
|
30
30
|
include_thinking = body[:include_thinking] == true
|
|
31
|
+
client_tool_passthrough = body[:client_tool_passthrough] == true
|
|
31
32
|
|
|
32
33
|
unless messages.is_a?(Array)
|
|
33
34
|
halt 400, { 'Content-Type' => 'application/json' },
|
|
@@ -103,6 +104,9 @@ module Legion
|
|
|
103
104
|
|
|
104
105
|
extra = {}
|
|
105
106
|
extra[:tier] = tier.to_sym if tier
|
|
107
|
+
metadata = { requested_tools: requested_tools }
|
|
108
|
+
metadata[:client_tool_passthrough] = true if client_tool_passthrough
|
|
109
|
+
metadata[:client_tool_request_count] = tools.size if tools.any?
|
|
106
110
|
|
|
107
111
|
pipeline_request = Legion::LLM::Inference::Request.build(
|
|
108
112
|
id: request_id,
|
|
@@ -112,7 +116,7 @@ module Legion
|
|
|
112
116
|
tools: tool_declarations,
|
|
113
117
|
caller: effective_caller,
|
|
114
118
|
conversation_id: conversation_id,
|
|
115
|
-
metadata:
|
|
119
|
+
metadata: metadata,
|
|
116
120
|
stream: streaming,
|
|
117
121
|
cache: { strategy: :default, cacheable: true },
|
|
118
122
|
extra: extra
|
|
@@ -123,7 +123,7 @@ module Legion
|
|
|
123
123
|
name: t[:name].to_s,
|
|
124
124
|
description: t[:description].to_s,
|
|
125
125
|
parameters: t[:parameters] || {},
|
|
126
|
-
source: { type: :client, executable:
|
|
126
|
+
source: { type: :client, executable: true }
|
|
127
127
|
)
|
|
128
128
|
rescue StandardError => e
|
|
129
129
|
tool_name = t.is_a?(Hash) ? t[:name] : nil
|
|
@@ -939,6 +939,23 @@ module Legion
|
|
|
939
939
|
!(@request.respond_to?(:suppress_tools) && @request.suppress_tools)
|
|
940
940
|
end
|
|
941
941
|
|
|
942
|
+
def client_tool_passthrough_enabled?
|
|
943
|
+
return false unless @request.respond_to?(:metadata)
|
|
944
|
+
|
|
945
|
+
metadata = @request.metadata || {}
|
|
946
|
+
value = metadata[:client_tool_passthrough] || metadata['client_tool_passthrough']
|
|
947
|
+
value == true
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
def non_executable_client_tool?(definition)
|
|
951
|
+
source = definition.respond_to?(:source) ? definition.source : {}
|
|
952
|
+
return false unless source.is_a?(Hash)
|
|
953
|
+
|
|
954
|
+
source_type = source[:type] || source['type']
|
|
955
|
+
executable = source.key?(:executable) ? source[:executable] : source['executable']
|
|
956
|
+
source_type.respond_to?(:to_sym) && source_type.to_sym == :client && executable != true
|
|
957
|
+
end
|
|
958
|
+
|
|
942
959
|
def add_pinned_special_tool_definitions(definitions)
|
|
943
960
|
Tools::Special.pinned_definitions.each do |definition|
|
|
944
961
|
next if definitions.any? { |existing| existing.name == definition.name }
|
|
@@ -957,6 +974,14 @@ module Legion
|
|
|
957
974
|
else
|
|
958
975
|
Types::ToolDefinition.from_tool_class(tool)
|
|
959
976
|
end
|
|
977
|
+
if non_executable_client_tool?(definition) && !client_tool_passthrough_enabled?
|
|
978
|
+
log.info(
|
|
979
|
+
"[llm][tools][inject] action=client_tool_skipped request_id=#{request_log_value(:id, 'unknown')} " \
|
|
980
|
+
"conversation_id=#{request_log_value(:conversation_id, 'none') || 'none'} name=#{definition.name} " \
|
|
981
|
+
'reason=client_passthrough_not_enabled'
|
|
982
|
+
)
|
|
983
|
+
return
|
|
984
|
+
end
|
|
960
985
|
return if gaia_tool_suppressed?(definition.name)
|
|
961
986
|
return if definitions.any? { |existing| existing.name == definition.name }
|
|
962
987
|
|
data/lib/legion/llm/version.rb
CHANGED