Class: Legion::CLI::Chat::Tools::ManageSchedules

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

Constant Summary collapse

DEFAULT_PORT =
4567
DEFAULT_HOST =
'127.0.0.1'
VALID_ACTIONS =
%w[list show logs create].freeze

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



106
107
108
109
110
111
112
113
# File 'lib/legion/cli/chat/tools/manage_schedules.rb', line 106

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



126
127
128
129
130
131
132
# File 'lib/legion/cli/chat/tools/manage_schedules.rb', line 126

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

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

.api_post(path, body) ⇒ Object



115
116
117
118
119
120
121
122
123
124
# File 'lib/legion/cli/chat/tools/manage_schedules.rb', line 115

def self.api_post(path, body)
  uri = URI("http://#{DEFAULT_HOST}:#{api_port}#{path}")
  http = Net::HTTP.new(uri.host, uri.port)
  http.open_timeout = 2
  http.read_timeout = 5
  req = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json')
  req.body = ::JSON.dump(body)
  response = http.request(req)
  ::JSON.parse(response.body, symbolize_names: true)
end

.call(action:) ⇒ Object



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

def self.call(action:, **)
  action = action.to_s.strip
  return "Invalid action: #{action}. Use: #{VALID_ACTIONS.join(', ')}" unless VALID_ACTIONS.include?(action)

  send(:"handle_#{action}", **)
rescue Errno::ECONNREFUSED
  'Legion daemon not running (cannot reach schedules API).'
rescue StandardError => e
  Legion::Logging.warn("ManageSchedules#execute failed: #{e.message}") if defined?(Legion::Logging)
  "Error managing schedules: #{e.message}"
end

.extract_collection(data) ⇒ Object



100
101
102
103
104
# File 'lib/legion/cli/chat/tools/manage_schedules.rb', line 100

def self.extract_collection(data)
  entries = data[:data] || data
  entries = [entries] if entries.is_a?(Hash) && !entries.key?(:error)
  Array(entries).reject { |e| e.is_a?(Hash) && e.key?(:error) }
end

.handle_create(function_id: nil, cron: nil) ⇒ Object



89
90
91
92
93
94
95
96
97
98
# File 'lib/legion/cli/chat/tools/manage_schedules.rb', line 89

def self.handle_create(function_id: nil, cron: nil, **)
  return 'function_id is required for the "create" action.' unless function_id
  return 'cron expression is required for the "create" action.' unless cron

  data = api_post('/api/schedules', { function_id: function_id.to_i, cron: cron })
  s = data[:data] || data
  return "Failed to create schedule: #{s[:error]}" if s[:error]

  "Schedule created (id: #{s[:id]}, cron: #{cron}, function: #{function_id})"
end

.handle_listObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/legion/cli/chat/tools/manage_schedules.rb', line 48

def self.handle_list(**)
  data = api_get('/api/schedules')
  entries = extract_collection(data)
  return 'No schedules found.' if entries.empty?

  lines = ["Schedules (#{entries.size}):\n"]
  entries.each do |s|
    schedule = s[:cron] || "every #{s[:interval]}s"
    status = s[:active] ? 'active' : 'inactive'
    lines << "  ##{s[:id]} [#{status}] #{schedule} -> function #{s[:function_id] || '?'}"
    lines << "    #{s[:description]}" if s[:description]
  end
  lines.join("\n")
end

.handle_logs(schedule_id: nil) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/legion/cli/chat/tools/manage_schedules.rb', line 75

def self.handle_logs(schedule_id: nil, **)
  return 'schedule_id is required for the "logs" action.' unless schedule_id

  data = api_get("/api/schedules/#{schedule_id}/logs")
  entries = extract_collection(data)
  return "No logs for schedule ##{schedule_id}." if entries.empty?

  lines = ["Logs for Schedule ##{schedule_id} (#{entries.size}):\n"]
  entries.first(10).each do |log|
    lines << "  [#{log[:started_at]}] #{log[:status] || '?'}: #{log[:message] || '-'}"
  end
  lines.join("\n")
end

.handle_show(schedule_id: nil) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/legion/cli/chat/tools/manage_schedules.rb', line 63

def self.handle_show(schedule_id: nil, **)
  return 'schedule_id is required for the "show" action.' unless schedule_id

  data = api_get("/api/schedules/#{schedule_id}")
  s = data[:data] || data
  return "Schedule ##{schedule_id} not found." if s[:error]

  lines = ["Schedule ##{schedule_id}:\n"]
  s.each { |key, val| lines << "  #{key}: #{val}" unless val.nil? }
  lines.join("\n")
end