legionio 1.4.122 → 1.4.123
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/alerts.rb +2 -1
- data/lib/legion/api/acp.rb +8 -4
- data/lib/legion/api/auth_human.rb +4 -2
- data/lib/legion/api/auth_saml.rb +6 -3
- data/lib/legion/api/auth_worker.rb +2 -1
- data/lib/legion/api/capacity.rb +2 -1
- data/lib/legion/api/catalog.rb +6 -3
- data/lib/legion/api/events.rb +2 -1
- data/lib/legion/api/gaia.rb +2 -1
- data/lib/legion/api/governance.rb +2 -1
- data/lib/legion/api/graphql/resolvers/extensions.rb +4 -2
- data/lib/legion/api/graphql/resolvers/node.rb +4 -2
- data/lib/legion/api/graphql/resolvers/tasks.rb +4 -2
- data/lib/legion/api/graphql/resolvers/workers.rb +4 -2
- data/lib/legion/api/helpers.rb +4 -2
- data/lib/legion/api/marketplace.rb +9 -3
- data/lib/legion/api/middleware/auth.rb +10 -5
- data/lib/legion/api/middleware/rate_limit.rb +2 -1
- data/lib/legion/api/org_chart.rb +2 -1
- data/lib/legion/api/prompts.rb +2 -1
- data/lib/legion/api/transport.rb +6 -3
- data/lib/legion/api/workflow.rb +2 -1
- data/lib/legion/audit.rb +2 -1
- data/lib/legion/catalog.rb +3 -1
- data/lib/legion/chat/notification_bridge.rb +2 -1
- data/lib/legion/cli/acp_command.rb +3 -1
- data/lib/legion/cli/auth_command.rb +7 -1
- data/lib/legion/cli/chat/agent_registry.rb +2 -1
- data/lib/legion/cli/chat/checkpoint.rb +4 -2
- data/lib/legion/cli/chat/context.rb +4 -3
- data/lib/legion/cli/chat/extension_tool_loader.rb +4 -2
- data/lib/legion/cli/chat/markdown_renderer.rb +2 -1
- data/lib/legion/cli/chat/session.rb +2 -1
- data/lib/legion/cli/chat/subagent.rb +6 -2
- data/lib/legion/cli/chat/tool_registry.rb +4 -3
- data/lib/legion/cli/chat/tools/edit_file.rb +1 -0
- data/lib/legion/cli/chat/tools/read_file.rb +1 -0
- data/lib/legion/cli/chat/tools/run_command.rb +3 -1
- data/lib/legion/cli/chat/tools/save_memory.rb +1 -0
- data/lib/legion/cli/chat/tools/search_content.rb +7 -3
- data/lib/legion/cli/chat/tools/search_files.rb +1 -0
- data/lib/legion/cli/chat/tools/search_memory.rb +1 -0
- data/lib/legion/cli/chat/tools/spawn_agent.rb +1 -0
- data/lib/legion/cli/chat/tools/web_search.rb +2 -0
- data/lib/legion/cli/chat/tools/write_file.rb +1 -0
- data/lib/legion/cli/chat/web_search.rb +4 -2
- data/lib/legion/cli/chat_command.rb +21 -8
- data/lib/legion/cli/check/privacy_check.rb +6 -3
- data/lib/legion/cli/check_command.rb +4 -3
- data/lib/legion/cli/coldstart_command.rb +4 -2
- data/lib/legion/cli/config_command.rb +2 -1
- data/lib/legion/cli/config_scaffold.rb +2 -1
- data/lib/legion/cli/connection.rb +2 -2
- data/lib/legion/cli/cost/data_client.rb +2 -1
- data/lib/legion/cli/dashboard/data_fetcher.rb +2 -1
- data/lib/legion/cli/dashboard_command.rb +1 -0
- data/lib/legion/cli/detect_command.rb +2 -1
- data/lib/legion/cli/doctor/bundle_check.rb +2 -1
- data/lib/legion/cli/doctor/cache_check.rb +2 -1
- data/lib/legion/cli/doctor/database_check.rb +2 -1
- data/lib/legion/cli/doctor/extensions_check.rb +2 -1
- data/lib/legion/cli/doctor/pid_check.rb +2 -1
- data/lib/legion/cli/doctor/rabbitmq_check.rb +4 -2
- data/lib/legion/cli/doctor/vault_check.rb +2 -1
- data/lib/legion/cli/doctor_command.rb +1 -0
- data/lib/legion/cli/gaia_command.rb +4 -2
- data/lib/legion/cli/init/environment_detector.rb +4 -2
- data/lib/legion/cli/lex_cli_manifest.rb +2 -1
- data/lib/legion/cli/lex_command.rb +8 -4
- data/lib/legion/cli/llm_command.rb +9 -5
- data/lib/legion/cli/marketplace_command.rb +2 -1
- data/lib/legion/cli/payroll_command.rb +3 -0
- data/lib/legion/cli/plan_command.rb +2 -1
- data/lib/legion/cli/setup_command.rb +8 -4
- data/lib/legion/cli/start.rb +2 -1
- data/lib/legion/cli/status.rb +2 -1
- data/lib/legion/cli/task_command.rb +6 -3
- data/lib/legion/cli/tty_command.rb +1 -0
- data/lib/legion/cli/update_command.rb +4 -2
- data/lib/legion/cli.rb +10 -4
- data/lib/legion/cluster/leader.rb +2 -1
- data/lib/legion/cluster/lock.rb +8 -4
- data/lib/legion/digital_worker/value_metrics.rb +2 -1
- data/lib/legion/docs/site_generator.rb +8 -6
- data/lib/legion/extensions/actors/subscription.rb +2 -1
- data/lib/legion/extensions/core.rb +2 -2
- data/lib/legion/extensions/permissions.rb +6 -3
- data/lib/legion/extensions.rb +12 -6
- data/lib/legion/graph/builder.rb +2 -1
- data/lib/legion/guardrails.rb +2 -1
- data/lib/legion/lock.rb +8 -4
- data/lib/legion/metrics.rb +2 -1
- data/lib/legion/notebook/renderer.rb +2 -1
- data/lib/legion/phi/access_log.rb +2 -1
- data/lib/legion/phi/erasure.rb +4 -2
- data/lib/legion/phi.rb +4 -2
- data/lib/legion/process.rb +4 -2
- data/lib/legion/process_role.rb +6 -1
- data/lib/legion/region/failover.rb +2 -1
- data/lib/legion/region.rb +14 -7
- data/lib/legion/registry/governance.rb +2 -1
- data/lib/legion/registry/persistence.rb +2 -1
- data/lib/legion/runner.rb +3 -2
- data/lib/legion/service.rb +10 -6
- data/lib/legion/telemetry/open_inference.rb +18 -9
- data/lib/legion/telemetry/safety_metrics.rb +4 -2
- data/lib/legion/telemetry.rb +14 -7
- data/lib/legion/tenants.rb +2 -1
- data/lib/legion/version.rb +1 -1
- data/lib/legion/webhooks.rb +8 -4
- 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: 6d78fc201a2601de3ce04849d24c9234c75bd77f6cdb3b46ca700f7cdd6fcc9f
|
|
4
|
+
data.tar.gz: 5746d467cb709dbf02837ebd2d4288dbe137d234c8f6e1e3b3445dcd899d3515
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 106274f7798ddf16c3da87f2c0ba204e98c0f8c8d9dedf312376fc8cbde8dbac447306cfd76c6cb0a5e210a22db9304fc37f5e3305f1cd80d918514aad80b4b4
|
|
7
|
+
data.tar.gz: 54ebdc455f6f5f86a0564809a67d6f3edffc20b7c3f438956382d32bff16d2b3469f51d4a48c1a30c312edfe0ad2d81abacc4962a96e79e7669d652cb4644605
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Legion Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.123] - 2026-03-22
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Add logging to silent rescue blocks: all rescue blocks now capture the exception variable and emit `Legion::Logging.debug` or `.warn` calls so errors are visible in logs rather than silently swallowed
|
|
7
|
+
|
|
3
8
|
## [1.4.122] - 2026-03-22
|
|
4
9
|
|
|
5
10
|
### Added
|
data/lib/legion/alerts.rb
CHANGED
|
@@ -117,7 +117,8 @@ module Legion
|
|
|
117
117
|
def load_rules
|
|
118
118
|
custom = begin
|
|
119
119
|
Legion::Settings[:alerts][:rules]
|
|
120
|
-
rescue StandardError
|
|
120
|
+
rescue StandardError => e
|
|
121
|
+
Legion::Logging.debug "Alerts#load_rules failed to read settings: #{e.message}" if defined?(Legion::Logging)
|
|
121
122
|
nil
|
|
122
123
|
end
|
|
123
124
|
custom && !custom.empty? ? custom : DEFAULT_RULES
|
data/lib/legion/api/acp.rb
CHANGED
|
@@ -7,12 +7,14 @@ module Legion
|
|
|
7
7
|
def build_agent_card
|
|
8
8
|
name = begin
|
|
9
9
|
Legion::Settings[:client][:name]
|
|
10
|
-
rescue StandardError
|
|
10
|
+
rescue StandardError => e
|
|
11
|
+
Legion::Logging.debug "Acp#build_agent_card failed to read client name: #{e.message}" if defined?(Legion::Logging)
|
|
11
12
|
'legion'
|
|
12
13
|
end
|
|
13
14
|
port = begin
|
|
14
15
|
settings.port || 4567
|
|
15
|
-
rescue StandardError
|
|
16
|
+
rescue StandardError => e
|
|
17
|
+
Legion::Logging.debug "Acp#build_agent_card failed to read port: #{e.message}" if defined?(Legion::Logging)
|
|
16
18
|
4567
|
|
17
19
|
end
|
|
18
20
|
{
|
|
@@ -34,7 +36,8 @@ module Legion
|
|
|
34
36
|
else
|
|
35
37
|
[]
|
|
36
38
|
end
|
|
37
|
-
rescue StandardError
|
|
39
|
+
rescue StandardError => e
|
|
40
|
+
Legion::Logging.warn "Acp#discover_capabilities failed: #{e.message}" if defined?(Legion::Logging)
|
|
38
41
|
[]
|
|
39
42
|
end
|
|
40
43
|
|
|
@@ -42,7 +45,8 @@ module Legion
|
|
|
42
45
|
return nil unless defined?(Legion::Data)
|
|
43
46
|
|
|
44
47
|
Legion::Data::Model::Task[id.to_i]&.values
|
|
45
|
-
rescue StandardError
|
|
48
|
+
rescue StandardError => e
|
|
49
|
+
Legion::Logging.warn "Acp#find_task failed for id=#{id}: #{e.message}" if defined?(Legion::Logging)
|
|
46
50
|
nil
|
|
47
51
|
end
|
|
48
52
|
|
|
@@ -20,7 +20,8 @@ module Legion
|
|
|
20
20
|
return entra if entra.is_a?(Hash)
|
|
21
21
|
|
|
22
22
|
{}
|
|
23
|
-
rescue StandardError
|
|
23
|
+
rescue StandardError => e
|
|
24
|
+
Legion::Logging.debug "AuthHuman#resolve_entra_settings failed: #{e.message}" if defined?(Legion::Logging)
|
|
24
25
|
{}
|
|
25
26
|
end
|
|
26
27
|
|
|
@@ -37,7 +38,8 @@ module Legion
|
|
|
37
38
|
return nil unless response.is_a?(Net::HTTPSuccess)
|
|
38
39
|
|
|
39
40
|
Legion::JSON.load(response.body)
|
|
40
|
-
rescue StandardError
|
|
41
|
+
rescue StandardError => e
|
|
42
|
+
Legion::Logging.warn "AuthHuman#exchange_code failed: #{e.message}" if defined?(Legion::Logging)
|
|
41
43
|
nil
|
|
42
44
|
end
|
|
43
45
|
|
data/lib/legion/api/auth_saml.rb
CHANGED
|
@@ -31,7 +31,8 @@ module Legion
|
|
|
31
31
|
return saml if saml.is_a?(Hash)
|
|
32
32
|
|
|
33
33
|
{}
|
|
34
|
-
rescue StandardError
|
|
34
|
+
rescue StandardError => e
|
|
35
|
+
Legion::Logging.debug "AuthSaml#resolve_saml_config failed: #{e.message}" if defined?(Legion::Logging)
|
|
35
36
|
{}
|
|
36
37
|
end
|
|
37
38
|
|
|
@@ -161,7 +162,8 @@ module Legion
|
|
|
161
162
|
names.each do |n|
|
|
162
163
|
v = attrs.multi(n)
|
|
163
164
|
return Array(v) if v
|
|
164
|
-
rescue StandardError
|
|
165
|
+
rescue StandardError => e
|
|
166
|
+
Legion::Logging.debug "AuthSaml#multi_attr failed for attr=#{n}: #{e.message}" if defined?(Legion::Logging)
|
|
165
167
|
nil
|
|
166
168
|
end
|
|
167
169
|
[]
|
|
@@ -169,7 +171,8 @@ module Legion
|
|
|
169
171
|
|
|
170
172
|
def safe_attr(attrs, name)
|
|
171
173
|
attrs[name]
|
|
172
|
-
rescue StandardError
|
|
174
|
+
rescue StandardError => e
|
|
175
|
+
Legion::Logging.debug "AuthSaml#safe_attr failed for name=#{name}: #{e.message}" if defined?(Legion::Logging)
|
|
173
176
|
nil
|
|
174
177
|
end
|
|
175
178
|
|
data/lib/legion/api/capacity.rb
CHANGED
|
@@ -45,7 +45,8 @@ module Legion
|
|
|
45
45
|
Legion::Data::Model::DigitalWorker.all.map do |w|
|
|
46
46
|
{ worker_id: w.worker_id, status: w.lifecycle_state }
|
|
47
47
|
end
|
|
48
|
-
rescue StandardError
|
|
48
|
+
rescue StandardError => e
|
|
49
|
+
Legion::Logging.warn "Capacity#fetch_worker_list failed: #{e.message}" if defined?(Legion::Logging)
|
|
49
50
|
[]
|
|
50
51
|
end
|
|
51
52
|
end
|
data/lib/legion/api/catalog.rb
CHANGED
|
@@ -45,7 +45,8 @@ module Legion
|
|
|
45
45
|
read_paths: declared[:read_paths],
|
|
46
46
|
write_paths: declared[:write_paths]
|
|
47
47
|
}
|
|
48
|
-
rescue StandardError
|
|
48
|
+
rescue StandardError => e
|
|
49
|
+
Legion::Logging.warn "API#build_catalog_permissions failed for #{name}: #{e.message}" if defined?(Legion::Logging)
|
|
49
50
|
{ sandbox: Legion::Extensions::Permissions.sandbox_path(name), read_paths: [], write_paths: [] }
|
|
50
51
|
end
|
|
51
52
|
|
|
@@ -61,7 +62,8 @@ module Legion
|
|
|
61
62
|
description: runner.values[:description]
|
|
62
63
|
}]
|
|
63
64
|
end
|
|
64
|
-
rescue StandardError
|
|
65
|
+
rescue StandardError => e
|
|
66
|
+
Legion::Logging.warn "API#build_catalog_runners failed for #{name}: #{e.message}" if defined?(Legion::Logging)
|
|
65
67
|
{}
|
|
66
68
|
end
|
|
67
69
|
|
|
@@ -74,7 +76,8 @@ module Legion
|
|
|
74
76
|
matched.map do |_hash, pattern|
|
|
75
77
|
{ intent: pattern[:intent_text], tool_chain: pattern[:tool_chain], confidence: pattern[:confidence] }
|
|
76
78
|
end
|
|
77
|
-
rescue StandardError
|
|
79
|
+
rescue StandardError => e
|
|
80
|
+
Legion::Logging.warn "API#build_catalog_known_intents failed for #{name}: #{e.message}" if defined?(Legion::Logging)
|
|
78
81
|
[]
|
|
79
82
|
end
|
|
80
83
|
end
|
data/lib/legion/api/events.rb
CHANGED
|
@@ -58,7 +58,8 @@ module Legion
|
|
|
58
58
|
event = queue.pop
|
|
59
59
|
data = Legion::JSON.dump(event.transform_keys(&:to_s))
|
|
60
60
|
out << "event: #{event[:event]}\ndata: #{data}\n\n"
|
|
61
|
-
rescue IOError, Errno::EPIPE
|
|
61
|
+
rescue IOError, Errno::EPIPE => e
|
|
62
|
+
Legion::Logging.debug "Events SSE stream broken for #{event[:event]}: #{e.message}" if defined?(Legion::Logging)
|
|
62
63
|
break
|
|
63
64
|
end
|
|
64
65
|
ensure
|
data/lib/legion/api/gaia.rb
CHANGED
|
@@ -36,7 +36,8 @@ module Legion
|
|
|
36
36
|
return nil unless Legion::Gaia.channel_registry
|
|
37
37
|
|
|
38
38
|
Legion::Gaia.channel_registry.adapter_for(:teams)
|
|
39
|
-
rescue StandardError
|
|
39
|
+
rescue StandardError => e
|
|
40
|
+
Legion::Logging.warn "Gaia#teams_adapter failed: #{e.message}" if defined?(Legion::Logging)
|
|
40
41
|
nil
|
|
41
42
|
end
|
|
42
43
|
end
|
|
@@ -14,7 +14,8 @@ module Legion
|
|
|
14
14
|
require 'legion/extensions/audit/runners/approval_queue'
|
|
15
15
|
runner = Object.new.extend(Legion::Extensions::Audit::Runners::ApprovalQueue)
|
|
16
16
|
runner.send(method, **)
|
|
17
|
-
rescue LoadError
|
|
17
|
+
rescue LoadError => e
|
|
18
|
+
Legion::Logging.warn "Governance#run_governance_runner failed to load lex-audit: #{e.message}" if defined?(Legion::Logging)
|
|
18
19
|
halt 503, json_error('service_unavailable', 'lex-audit not available', status_code: 503)
|
|
19
20
|
end
|
|
20
21
|
end
|
|
@@ -23,7 +23,8 @@ module Legion
|
|
|
23
23
|
dataset = Legion::Data::Model::Extension.order(:id)
|
|
24
24
|
dataset = dataset.where(status: status) if status
|
|
25
25
|
dataset.all.map { |e| extension_hash(e.values) }
|
|
26
|
-
rescue StandardError
|
|
26
|
+
rescue StandardError => e
|
|
27
|
+
Legion::Logging.warn "GraphQL::Extensions#resolve_from_data failed: #{e.message}" if defined?(Legion::Logging)
|
|
27
28
|
[]
|
|
28
29
|
end
|
|
29
30
|
|
|
@@ -34,7 +35,8 @@ module Legion
|
|
|
34
35
|
entries = entries.map { |e| e.is_a?(Hash) ? e : e.to_h }
|
|
35
36
|
entries = entries.select { |e| e[:status].to_s == status } if status
|
|
36
37
|
entries.map { |e| extension_hash(e) }
|
|
37
|
-
rescue StandardError
|
|
38
|
+
rescue StandardError => e
|
|
39
|
+
Legion::Logging.warn "GraphQL::Extensions#resolve_from_registry failed: #{e.message}" if defined?(Legion::Logging)
|
|
38
40
|
[]
|
|
39
41
|
end
|
|
40
42
|
|
|
@@ -17,7 +17,8 @@ module Legion
|
|
|
17
17
|
uptime: uptime,
|
|
18
18
|
ready: ready
|
|
19
19
|
}
|
|
20
|
-
rescue StandardError
|
|
20
|
+
rescue StandardError => e
|
|
21
|
+
Legion::Logging.warn "GraphQL::Node#resolve failed: #{e.message}" if defined?(Legion::Logging)
|
|
21
22
|
{ name: nil, version: nil, uptime: nil, ready: false }
|
|
22
23
|
end
|
|
23
24
|
|
|
@@ -27,7 +28,8 @@ module Legion
|
|
|
27
28
|
Legion::Process.started_at
|
|
28
29
|
|
|
29
30
|
(Time.now.utc - Legion::Process.started_at).to_i
|
|
30
|
-
rescue StandardError
|
|
31
|
+
rescue StandardError => e
|
|
32
|
+
Legion::Logging.debug "GraphQL::Node#calculate_uptime failed: #{e.message}" if defined?(Legion::Logging)
|
|
31
33
|
nil
|
|
32
34
|
end
|
|
33
35
|
|
|
@@ -11,7 +11,8 @@ module Legion
|
|
|
11
11
|
Legion::Data.connection
|
|
12
12
|
|
|
13
13
|
resolve_from_data(status: status, limit: limit)
|
|
14
|
-
rescue StandardError
|
|
14
|
+
rescue StandardError => e
|
|
15
|
+
Legion::Logging.warn "GraphQL::Tasks#resolve failed: #{e.message}" if defined?(Legion::Logging)
|
|
15
16
|
[]
|
|
16
17
|
end
|
|
17
18
|
|
|
@@ -22,7 +23,8 @@ module Legion
|
|
|
22
23
|
dataset = dataset.where(status: status) if status
|
|
23
24
|
dataset = dataset.limit(limit) if limit
|
|
24
25
|
dataset.all.map { |t| task_hash(t.values) }
|
|
25
|
-
rescue StandardError
|
|
26
|
+
rescue StandardError => e
|
|
27
|
+
Legion::Logging.warn "GraphQL::Tasks#resolve_from_data failed: #{e.message}" if defined?(Legion::Logging)
|
|
26
28
|
[]
|
|
27
29
|
end
|
|
28
30
|
|
|
@@ -29,7 +29,8 @@ module Legion
|
|
|
29
29
|
dataset = dataset.where(risk_tier: risk_tier) if risk_tier
|
|
30
30
|
dataset = dataset.limit(limit) if limit
|
|
31
31
|
dataset.all.map { |w| worker_hash(w.values) }
|
|
32
|
-
rescue StandardError
|
|
32
|
+
rescue StandardError => e
|
|
33
|
+
Legion::Logging.warn "GraphQL::Workers#resolve_from_data failed: #{e.message}" if defined?(Legion::Logging)
|
|
33
34
|
[]
|
|
34
35
|
end
|
|
35
36
|
|
|
@@ -54,7 +55,8 @@ module Legion
|
|
|
54
55
|
|
|
55
56
|
worker = Legion::Data::Model::DigitalWorker.first(id: id.to_i)
|
|
56
57
|
worker ? worker_hash(worker.values) : nil
|
|
57
|
-
rescue StandardError
|
|
58
|
+
rescue StandardError => e
|
|
59
|
+
Legion::Logging.warn "GraphQL::Workers#find_from_data failed for id=#{id}: #{e.message}" if defined?(Legion::Logging)
|
|
58
60
|
nil
|
|
59
61
|
end
|
|
60
62
|
|
data/lib/legion/api/helpers.rb
CHANGED
|
@@ -57,7 +57,8 @@ module Legion
|
|
|
57
57
|
return {} if body.nil? || body.empty?
|
|
58
58
|
|
|
59
59
|
Legion::JSON.load(body).transform_keys(&:to_sym)
|
|
60
|
-
rescue StandardError
|
|
60
|
+
rescue StandardError => e
|
|
61
|
+
Legion::Logging.warn "API#parse_request_body failed to parse JSON: #{e.message}" if defined?(Legion::Logging)
|
|
61
62
|
halt 400, json_error('invalid_json', 'request body is not valid JSON', status_code: 400)
|
|
62
63
|
end
|
|
63
64
|
|
|
@@ -87,7 +88,8 @@ module Legion
|
|
|
87
88
|
.select { |klass| klass < base_class }
|
|
88
89
|
.map { |klass| { name: klass.name } }
|
|
89
90
|
.sort_by { |h| h[:name].to_s }
|
|
90
|
-
rescue NameError
|
|
91
|
+
rescue NameError => e
|
|
92
|
+
Legion::Logging.debug "API#transport_subclasses failed for #{base_class}: #{e.message}" if defined?(Legion::Logging)
|
|
91
93
|
[]
|
|
92
94
|
end
|
|
93
95
|
|
|
@@ -12,7 +12,8 @@ module Legion
|
|
|
12
12
|
return nil if date_str.nil? || date_str.empty?
|
|
13
13
|
|
|
14
14
|
Date.parse(date_str.to_s)
|
|
15
|
-
rescue ArgumentError
|
|
15
|
+
rescue ArgumentError => e
|
|
16
|
+
Legion::Logging.debug "Marketplace#parse_sunset_date invalid date '#{date_str}': #{e.message}" if defined?(Legion::Logging)
|
|
16
17
|
nil
|
|
17
18
|
end
|
|
18
19
|
end
|
|
@@ -54,11 +55,12 @@ module Legion
|
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
|
|
57
|
-
def self.register_review_actions(app) # rubocop:disable Metrics/AbcSize
|
|
58
|
+
def self.register_review_actions(app) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
58
59
|
app.post '/api/marketplace/:name/submit' do
|
|
59
60
|
begin
|
|
60
61
|
Legion::Registry.submit_for_review(params[:name])
|
|
61
62
|
rescue ArgumentError => e
|
|
63
|
+
Legion::Logging.warn "API POST /api/marketplace/#{params[:name]}/submit: #{e.message}" if defined?(Legion::Logging)
|
|
62
64
|
halt 404, { 'Content-Type' => 'application/json' },
|
|
63
65
|
Legion::JSON.dump({ error: { code: 'not_found', message: e.message } })
|
|
64
66
|
end
|
|
@@ -70,6 +72,7 @@ module Legion
|
|
|
70
72
|
begin
|
|
71
73
|
Legion::Registry.approve(params[:name], notes: body[:notes])
|
|
72
74
|
rescue ArgumentError => e
|
|
75
|
+
Legion::Logging.warn "API POST /api/marketplace/#{params[:name]}/approve: #{e.message}" if defined?(Legion::Logging)
|
|
73
76
|
halt 404, { 'Content-Type' => 'application/json' },
|
|
74
77
|
Legion::JSON.dump({ error: { code: 'not_found', message: e.message } })
|
|
75
78
|
end
|
|
@@ -82,6 +85,7 @@ module Legion
|
|
|
82
85
|
begin
|
|
83
86
|
Legion::Registry.reject(params[:name], reason: body[:reason])
|
|
84
87
|
rescue ArgumentError => e
|
|
88
|
+
Legion::Logging.warn "API POST /api/marketplace/#{params[:name]}/reject: #{e.message}" if defined?(Legion::Logging)
|
|
85
89
|
halt 404, { 'Content-Type' => 'application/json' },
|
|
86
90
|
Legion::JSON.dump({ error: { code: 'not_found', message: e.message } })
|
|
87
91
|
end
|
|
@@ -93,12 +97,14 @@ module Legion
|
|
|
93
97
|
body = parse_request_body
|
|
94
98
|
sunset = begin
|
|
95
99
|
body[:sunset_date] ? Date.parse(body[:sunset_date].to_s) : nil
|
|
96
|
-
rescue ArgumentError
|
|
100
|
+
rescue ArgumentError => e
|
|
101
|
+
Legion::Logging.debug "Marketplace#deprecate invalid sunset_date '#{body[:sunset_date]}': #{e.message}" if defined?(Legion::Logging)
|
|
97
102
|
nil
|
|
98
103
|
end
|
|
99
104
|
begin
|
|
100
105
|
Legion::Registry.deprecate(params[:name], successor: body[:successor], sunset_date: sunset)
|
|
101
106
|
rescue ArgumentError => e
|
|
107
|
+
Legion::Logging.warn "API POST /api/marketplace/#{params[:name]}/deprecate: #{e.message}" if defined?(Legion::Logging)
|
|
102
108
|
halt 404, { 'Content-Type' => 'application/json' },
|
|
103
109
|
Legion::JSON.dump({ error: { code: 'not_found', message: e.message } })
|
|
104
110
|
end
|
|
@@ -107,7 +107,8 @@ module Legion
|
|
|
107
107
|
)
|
|
108
108
|
|
|
109
109
|
{ claims: claims, output_token: auth_result[:output_token] }
|
|
110
|
-
rescue StandardError
|
|
110
|
+
rescue StandardError => e
|
|
111
|
+
Legion::Logging.warn "Auth#verify_negotiate failed: #{e.message}" if defined?(Legion::Logging)
|
|
111
112
|
nil
|
|
112
113
|
end
|
|
113
114
|
|
|
@@ -120,7 +121,8 @@ module Legion
|
|
|
120
121
|
return {} unless defined?(Legion::Settings)
|
|
121
122
|
|
|
122
123
|
Legion::Settings.dig(:kerberos, :role_map) || {}
|
|
123
|
-
rescue StandardError
|
|
124
|
+
rescue StandardError => e
|
|
125
|
+
Legion::Logging.debug "Auth#kerberos_role_map failed: #{e.message}" if defined?(Legion::Logging)
|
|
124
126
|
{}
|
|
125
127
|
end
|
|
126
128
|
|
|
@@ -128,7 +130,8 @@ module Legion
|
|
|
128
130
|
return :entra unless defined?(Legion::Settings)
|
|
129
131
|
|
|
130
132
|
Legion::Settings.dig(:kerberos, :fallback) || :entra
|
|
131
|
-
rescue StandardError
|
|
133
|
+
rescue StandardError => e
|
|
134
|
+
Legion::Logging.debug "Auth#kerberos_fallback failed: #{e.message}" if defined?(Legion::Logging)
|
|
132
135
|
:entra
|
|
133
136
|
end
|
|
134
137
|
|
|
@@ -155,7 +158,8 @@ module Legion
|
|
|
155
158
|
return nil unless key
|
|
156
159
|
|
|
157
160
|
Legion::Crypt::JWT.verify(token, verification_key: key)
|
|
158
|
-
rescue Legion::Crypt::JWT::Error
|
|
161
|
+
rescue Legion::Crypt::JWT::Error => e
|
|
162
|
+
Legion::Logging.debug "Auth#verify_token failed: #{e.message}" if defined?(Legion::Logging)
|
|
159
163
|
nil
|
|
160
164
|
end
|
|
161
165
|
|
|
@@ -168,7 +172,8 @@ module Legion
|
|
|
168
172
|
def unauthorized(message)
|
|
169
173
|
body = Legion::JSON.dump({ error: { code: 401, message: message }, meta: { timestamp: Time.now.utc.iso8601 } })
|
|
170
174
|
[401, { 'content-type' => 'application/json' }, [body]]
|
|
171
|
-
rescue StandardError
|
|
175
|
+
rescue StandardError => e
|
|
176
|
+
Legion::Logging.warn "Auth#unauthorized JSON serialization failed: #{e.message}" if defined?(Legion::Logging)
|
|
172
177
|
[401, { 'content-type' => 'application/json' }, ["{\"error\":{\"code\":401,\"message\":\"#{message}\"}}"]]
|
|
173
178
|
end
|
|
174
179
|
end
|
|
@@ -71,7 +71,8 @@ module Legion
|
|
|
71
71
|
status, headers, body = @app.call(env)
|
|
72
72
|
[status, headers.merge(rate_limit_headers(result)), body]
|
|
73
73
|
end
|
|
74
|
-
rescue StandardError
|
|
74
|
+
rescue StandardError => e
|
|
75
|
+
Legion::Logging.warn "RateLimit#call failed, passing through: #{e.message}" if defined?(Legion::Logging)
|
|
75
76
|
@app.call(env)
|
|
76
77
|
end
|
|
77
78
|
|
data/lib/legion/api/org_chart.rb
CHANGED
data/lib/legion/api/prompts.rb
CHANGED
|
@@ -17,7 +17,8 @@ module Legion
|
|
|
17
17
|
define_method(:prompt_client) do
|
|
18
18
|
require 'legion/extensions/prompt/client'
|
|
19
19
|
Legion::Extensions::Prompt::Client.new
|
|
20
|
-
rescue LoadError
|
|
20
|
+
rescue LoadError => e
|
|
21
|
+
Legion::Logging.warn "Prompts#prompt_client failed to load lex-prompt: #{e.message}" if defined?(Legion::Logging)
|
|
21
22
|
halt 503, json_error('prompt_unavailable', 'lex-prompt is not loaded', status_code: 503)
|
|
22
23
|
end
|
|
23
24
|
end
|
data/lib/legion/api/transport.rb
CHANGED
|
@@ -14,17 +14,20 @@ module Legion
|
|
|
14
14
|
app.get '/api/transport' do
|
|
15
15
|
connected = begin
|
|
16
16
|
Legion::Settings[:transport][:connected]
|
|
17
|
-
rescue StandardError
|
|
17
|
+
rescue StandardError => e
|
|
18
|
+
Legion::Logging.debug "Transport#status failed to read connected setting: #{e.message}" if defined?(Legion::Logging)
|
|
18
19
|
false
|
|
19
20
|
end
|
|
20
21
|
session_open = begin
|
|
21
22
|
Legion::Transport::Connection.session_open?
|
|
22
|
-
rescue StandardError
|
|
23
|
+
rescue StandardError => e
|
|
24
|
+
Legion::Logging.debug "Transport#status failed to check session_open: #{e.message}" if defined?(Legion::Logging)
|
|
23
25
|
false
|
|
24
26
|
end
|
|
25
27
|
channel_open = begin
|
|
26
28
|
Legion::Transport::Connection.channel_open?
|
|
27
|
-
rescue StandardError
|
|
29
|
+
rescue StandardError => e
|
|
30
|
+
Legion::Logging.debug "Transport#status failed to check channel_open: #{e.message}" if defined?(Legion::Logging)
|
|
28
31
|
false
|
|
29
32
|
end
|
|
30
33
|
connector = defined?(Legion::Transport::TYPE) ? Legion::Transport::TYPE.to_s : 'unknown'
|
data/lib/legion/api/workflow.rb
CHANGED
|
@@ -36,7 +36,8 @@ module Legion
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
{ nodes: nodes, edges: edges }
|
|
39
|
-
rescue StandardError
|
|
39
|
+
rescue StandardError => e
|
|
40
|
+
Legion::Logging.warn "Workflow#build_relationship_graph failed: #{e.message}" if defined?(Legion::Logging)
|
|
40
41
|
{ nodes: [], edges: [] }
|
|
41
42
|
end
|
|
42
43
|
end
|
data/lib/legion/audit.rb
CHANGED
|
@@ -81,7 +81,8 @@ module Legion
|
|
|
81
81
|
|
|
82
82
|
def node_name
|
|
83
83
|
Legion::Settings[:client][:hostname]
|
|
84
|
-
rescue StandardError
|
|
84
|
+
rescue StandardError => e
|
|
85
|
+
Legion::Logging.debug "Audit#node_name failed to read hostname: #{e.message}" if defined?(Legion::Logging)
|
|
85
86
|
'unknown'
|
|
86
87
|
end
|
|
87
88
|
end
|
data/lib/legion/catalog.rb
CHANGED
|
@@ -24,7 +24,8 @@ module Legion
|
|
|
24
24
|
return [] unless defined?(Legion::MCP) && Legion::MCP.respond_to?(:tools)
|
|
25
25
|
|
|
26
26
|
Legion::MCP.tools.map { |t| { name: t[:name], description: t[:description] } }
|
|
27
|
-
rescue StandardError
|
|
27
|
+
rescue StandardError => e
|
|
28
|
+
Legion::Logging.warn "Catalog#collect_mcp_tools failed: #{e.message}" if defined?(Legion::Logging)
|
|
28
29
|
[]
|
|
29
30
|
end
|
|
30
31
|
|
|
@@ -42,6 +43,7 @@ module Legion
|
|
|
42
43
|
end
|
|
43
44
|
{ status: response.code.to_i, body: response.body }
|
|
44
45
|
rescue StandardError => e
|
|
46
|
+
Legion::Logging.warn "Catalog#post_json failed for #{url}: #{e.message}" if defined?(Legion::Logging)
|
|
45
47
|
{ error: e.message }
|
|
46
48
|
end
|
|
47
49
|
end
|
|
@@ -69,7 +69,8 @@ module Legion
|
|
|
69
69
|
def load_patterns
|
|
70
70
|
custom = begin
|
|
71
71
|
Legion::Settings.dig(:chat, :notifications, :patterns)
|
|
72
|
-
rescue StandardError
|
|
72
|
+
rescue StandardError => e
|
|
73
|
+
Legion::Logging.debug "NotificationBridge#load_patterns failed to read settings: #{e.message}" if defined?(Legion::Logging)
|
|
73
74
|
nil
|
|
74
75
|
end
|
|
75
76
|
return DEFAULT_PATTERNS unless custom
|
|
@@ -29,7 +29,8 @@ module Legion
|
|
|
29
29
|
def llm_available?
|
|
30
30
|
require 'legion/llm'
|
|
31
31
|
true
|
|
32
|
-
rescue LoadError
|
|
32
|
+
rescue LoadError => e
|
|
33
|
+
Legion::Logging.debug("AcpCommand#llm_available? legion-llm not available: #{e.message}") if defined?(Legion::Logging)
|
|
33
34
|
false
|
|
34
35
|
end
|
|
35
36
|
|
|
@@ -38,6 +39,7 @@ module Legion
|
|
|
38
39
|
Connection.ensure_settings
|
|
39
40
|
Connection.ensure_llm
|
|
40
41
|
rescue StandardError => e
|
|
42
|
+
Legion::Logging.warn("AcpCommand#setup_llm failed: #{e.message}") if defined?(Legion::Logging)
|
|
41
43
|
warn("[lex-acp] LLM setup failed: #{e.message} — running without prompt support")
|
|
42
44
|
end
|
|
43
45
|
end
|
|
@@ -103,6 +103,7 @@ module Legion
|
|
|
103
103
|
response = send_negotiate_request(api_url, token)
|
|
104
104
|
handle_negotiate_response(response)
|
|
105
105
|
rescue StandardError => e
|
|
106
|
+
Legion::Logging.error("Auth#kerberos failed: #{e.message}") if defined?(Legion::Logging)
|
|
106
107
|
say "Kerberos auth error: #{e.message}", :red
|
|
107
108
|
end
|
|
108
109
|
|
|
@@ -141,7 +142,12 @@ module Legion
|
|
|
141
142
|
|
|
142
143
|
def handle_negotiate_response(response)
|
|
143
144
|
if response.code.to_i == 200
|
|
144
|
-
body =
|
|
145
|
+
body = begin
|
|
146
|
+
::JSON.parse(response.body)
|
|
147
|
+
rescue ::JSON::ParserError => e
|
|
148
|
+
Legion::Logging.debug("Auth#handle_negotiate_response JSON parse failed: #{e.message}") if defined?(Legion::Logging)
|
|
149
|
+
{}
|
|
150
|
+
end
|
|
145
151
|
data = body.is_a?(Hash) ? (body['data'] || body) : {}
|
|
146
152
|
token_val = data['token']
|
|
147
153
|
if token_val
|
|
@@ -70,7 +70,8 @@ module Legion
|
|
|
70
70
|
require 'yaml'
|
|
71
71
|
YAML.safe_load(content, permitted_classes: [Symbol])
|
|
72
72
|
end
|
|
73
|
-
rescue StandardError
|
|
73
|
+
rescue StandardError => e
|
|
74
|
+
Legion::Logging.debug("AgentRegistry#parse_file failed for #{path}: #{e.message}") if defined?(Legion::Logging)
|
|
74
75
|
nil
|
|
75
76
|
end
|
|
76
77
|
|
|
@@ -107,7 +107,8 @@ module Legion
|
|
|
107
107
|
safe_name = entry.path.gsub('/', '_').gsub('\\', '_')
|
|
108
108
|
backup_path = File.join(storage_dir, "#{@entries.length}_#{safe_name}")
|
|
109
109
|
File.write(backup_path, entry.content, encoding: 'utf-8')
|
|
110
|
-
rescue StandardError
|
|
110
|
+
rescue StandardError => e
|
|
111
|
+
Legion::Logging.warn("Checkpoint#persist_entry failed for #{entry.path}: #{e.message}") if defined?(Legion::Logging)
|
|
111
112
|
# In-memory fallback is always available via @entries
|
|
112
113
|
nil
|
|
113
114
|
end
|
|
@@ -117,7 +118,8 @@ module Legion
|
|
|
117
118
|
|
|
118
119
|
FileUtils.rm_rf(@storage_dir)
|
|
119
120
|
@storage_dir = nil
|
|
120
|
-
rescue StandardError
|
|
121
|
+
rescue StandardError => e
|
|
122
|
+
Legion::Logging.warn("Checkpoint#cleanup_storage failed: #{e.message}") if defined?(Legion::Logging)
|
|
121
123
|
nil
|
|
122
124
|
end
|
|
123
125
|
end
|
|
@@ -54,8 +54,8 @@ module Legion
|
|
|
54
54
|
end
|
|
55
55
|
parts << "Extension tools available: #{ext_names.join(', ')}"
|
|
56
56
|
end
|
|
57
|
-
rescue LoadError
|
|
58
|
-
# ExtensionToolLoader not available
|
|
57
|
+
rescue LoadError => e
|
|
58
|
+
Legion::Logging.debug("Context#to_system_prompt ExtensionToolLoader not available: #{e.message}") if defined?(Legion::Logging)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
extra_dirs.each do |dir|
|
|
@@ -99,7 +99,8 @@ module Legion
|
|
|
99
99
|
|
|
100
100
|
output = `cd #{Shellwords.escape(dir)} && git status --porcelain 2>/dev/null`
|
|
101
101
|
!output.strip.empty?
|
|
102
|
-
rescue StandardError
|
|
102
|
+
rescue StandardError => e
|
|
103
|
+
Legion::Logging.debug("Context#detect_git_dirty failed: #{e.message}") if defined?(Legion::Logging)
|
|
103
104
|
false
|
|
104
105
|
end
|
|
105
106
|
|
|
@@ -51,7 +51,8 @@ module Legion
|
|
|
51
51
|
return nil unless defined?(Legion::Settings)
|
|
52
52
|
|
|
53
53
|
Legion::Settings[:extensions]&.[](extension_name.to_sym)
|
|
54
|
-
rescue StandardError
|
|
54
|
+
rescue StandardError => e
|
|
55
|
+
Legion::Logging.warn("ExtensionToolLoader#extension_settings failed for #{extension_name}: #{e.message}") if defined?(Legion::Logging)
|
|
55
56
|
nil
|
|
56
57
|
end
|
|
57
58
|
|
|
@@ -82,7 +83,8 @@ module Legion
|
|
|
82
83
|
gem_spec = Gem::Specification.find_by_name(info[:gem_name])
|
|
83
84
|
ext_path = "#{gem_spec.gem_dir}/lib/legion/extensions/#{name}"
|
|
84
85
|
[name, ext_path]
|
|
85
|
-
rescue Gem::MissingSpecError
|
|
86
|
+
rescue Gem::MissingSpecError => e
|
|
87
|
+
Legion::Logging.debug("ExtensionToolLoader#loaded_extension_paths gem not found for #{name}: #{e.message}") if defined?(Legion::Logging)
|
|
86
88
|
nil
|
|
87
89
|
end&.compact || []
|
|
88
90
|
end
|