Class: Legion::CLI::Chat::Tools::SystemStatus

Inherits:
Tools::Base
  • Object
show all
Defined in:
lib/legion/cli/chat/tools/system_status.rb

Constant Summary collapse

DEFAULT_PORT =
4567
DEFAULT_HOST =
'127.0.0.1'

Class Method Summary collapse

Methods inherited from Tools::Base

deferred, deferred?, description, error_response, extension, handle_exception, input_schema, log, mcp_category, mcp_tier, runner, sticky, tags, text_response, tool_name, trigger_words

Class Method Details

.api_get(path) ⇒ Object



101
102
103
104
105
106
107
108
# File 'lib/legion/cli/chat/tools/system_status.rb', line 101

def self.api_get(path)
  uri = URI("http://#{DEFAULT_HOST}:#{api_port}#{path}")
  http = Net::HTTP.new(uri.host, uri.port)
  http.open_timeout = 2
  http.read_timeout = 5
  response = http.get(uri.request_uri)
  ::JSON.parse(response.body, symbolize_names: true)
end

.api_portObject



110
111
112
113
114
115
116
# File 'lib/legion/cli/chat/tools/system_status.rb', line 110

def self.api_port
  return DEFAULT_PORT unless defined?(Legion::Settings)

  Legion::Settings[:api]&.dig(:port) || DEFAULT_PORT
rescue StandardError
  DEFAULT_PORT
end

.callObject



26
27
28
29
30
31
32
33
34
35
# File 'lib/legion/cli/chat/tools/system_status.rb', line 26

def self.call
  health = fetch_health
  ready = fetch_ready
  format_status(health, ready)
rescue Errno::ECONNREFUSED
  format('Legion daemon not running (cannot connect to API on port %d).', api_port)
rescue StandardError => e
  Legion::Logging.warn("SystemStatus#execute failed: #{e.message}") if defined?(Legion::Logging)
  "Error checking system status: #{e.message}"
end

.fetch_healthObject



37
38
39
40
41
42
43
44
# File 'lib/legion/cli/chat/tools/system_status.rb', line 37

def self.fetch_health
  api_get('/api/health')
rescue Errno::ECONNREFUSED
  raise
rescue StandardError => e
  Legion::Logging.debug("SystemStatus#fetch_health failed: #{e.message}") if defined?(Legion::Logging)
  nil
end

.fetch_readyObject



46
47
48
49
50
51
52
53
# File 'lib/legion/cli/chat/tools/system_status.rb', line 46

def self.fetch_ready
  api_get('/api/ready')
rescue Errno::ECONNREFUSED
  raise
rescue StandardError => e
  Legion::Logging.debug("SystemStatus#fetch_ready failed: #{e.message}") if defined?(Legion::Logging)
  nil
end

.format_status(health, ready) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/legion/cli/chat/tools/system_status.rb', line 55

def self.format_status(health, ready)
  lines = ["Legion System Status\n"]

  if health
    lines << "  Status: #{health[:status] || 'unknown'}"
    lines << "  Version: #{health[:version]}" if health[:version]
    lines << "  Node: #{health[:node]}" if health[:node]
    lines << "  Uptime: #{format_uptime(health[:uptime_seconds])}" if health[:uptime_seconds]
    lines << "  PID: #{health[:pid]}" if health[:pid]
  else
    lines << '  Health endpoint: unreachable'
  end

  if ready
    components = ready[:components] || ready[:data] || {}
    if components.is_a?(Hash) && components.any?
      lines << "\n  Components:"
      components.each do |name, status|
        icon = status == true ? 'ready' : 'not ready'
        lines << "    #{name}: #{icon}"
      end
      ready_count = components.values.count(true)
      lines << "  Overall: #{ready_count}/#{components.size} ready"
    end

    lines << "  Extensions: #{ready[:extension_count]}" if ready[:extension_count]
  end

  lines.join("\n")
end

.format_uptime(seconds) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/legion/cli/chat/tools/system_status.rb', line 86

def self.format_uptime(seconds)
  return 'unknown' unless seconds

  seconds = seconds.to_i
  days = seconds / 86_400
  hours = (seconds % 86_400) / 3600
  mins = (seconds % 3600) / 60
  parts = []
  parts << "#{days}d" if days.positive?
  parts << "#{hours}h" if hours.positive?
  parts << "#{mins}m" if mins.positive?
  parts << "#{seconds % 60}s" if parts.empty?
  parts.join(' ')
end