Class: Legion::CLI::Chat::Tools::ManageTasks
Constant Summary
collapse
- VALID_ACTIONS =
%w[list show logs trigger].freeze
- 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
146
147
148
149
150
151
152
153
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 146
def self.api_get(path)
uri = URI("http://#{DEFAULT_HOST}:#{api_port}#{path}")
http = Net::HTTP.new(uri.host, uri.port)
http.open_timeout = 3
http.read_timeout = 10
response = http.get(uri.request_uri)
::JSON.parse(response.body, symbolize_names: true)
end
|
.api_port ⇒ Object
166
167
168
169
170
171
172
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 166
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
155
156
157
158
159
160
161
162
163
164
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 155
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 = 3
http.read_timeout = 15
request = Net::HTTP::Post.new(uri.request_uri, 'Content-Type' => 'application/json')
request.body = ::JSON.generate(body)
response = http.request(request)
::JSON.parse(response.body, symbolize_names: true)
end
|
.call(action:) ⇒ Object
40
41
42
43
44
45
46
47
48
49
50
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 40
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 task API).'
rescue StandardError => e
Legion::Logging.warn("ManageTasks#execute failed: #{e.message}") if defined?(Legion::Logging)
"Error managing tasks: #{e.message}"
end
|
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 115
def self.format_task_detail(task)
lines = ["Task ##{task[:id]}\n"]
lines << " Status: #{task[:status]}"
lines << " Runner: #{task[:runner_class]}"
lines << " Function: #{task[:function]}" if task[:function]
lines << " Created: #{task[:created_at]}"
lines << " Updated: #{task[:updated_at]}" if task[:updated_at]
if task[:metering]
m = task[:metering]
lines << "\n Metering:"
lines << " Total tokens: #{m[:total_tokens]}"
lines << " Input/Output: #{m[:input_tokens]}/#{m[:output_tokens]}"
lines << " Calls: #{m[:total_calls]}"
lines << " Avg latency: #{m[:avg_latency_ms]}ms"
lines << " Provider: #{Array(m[:provider]).join(', ')}" if m[:provider]
lines << " Model: #{Array(m[:model]).join(', ')}" if m[:model]
end
lines.join("\n")
end
|
106
107
108
109
110
111
112
113
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 106
def self.format_task_list(tasks)
lines = ["Recent Tasks (#{tasks.size}):\n"]
tasks.each do |t|
status_str = t[:status] || 'unknown'
lines << " ##{t[:id]} [#{status_str}] #{t[:runner_class]}##{t[:function]} (#{t[:created_at]})"
end
lines.join("\n")
end
|
137
138
139
140
141
142
143
144
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 137
def self.format_task_logs(task_id, logs)
lines = ["Logs for Task ##{task_id} (#{logs.size} entries):\n"]
logs.each do |log|
ts = log[:created_at] || log[:timestamp]
lines << " [#{ts}] #{log[:level] || 'info'}: #{log[:message]}"
end
lines.join("\n")
end
|
.handle_list(status: nil, limit: nil) ⇒ Object
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 52
def self.handle_list(status: nil, limit: nil, **)
path = '/api/tasks'
params = []
params << "status=#{status}" if status
params << "per_page=#{limit || 10}"
path += "?#{params.join('&')}" unless params.empty?
data = api_get(path)
return "API error: #{data[:error]}" if data[:error]
tasks = data[:data] || data[:items] || data
tasks = [tasks] if tasks.is_a?(Hash)
return 'No tasks found.' if !tasks.is_a?(Array) || tasks.empty?
format_task_list(tasks)
end
|
.handle_logs(task_id: nil) ⇒ Object
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 79
def self.handle_logs(task_id: nil, **)
return 'task_id is required for "logs"' unless task_id
data = api_get("/api/tasks/#{task_id}/logs")
return "API error: #{data[:error]}" if data[:error]
logs = data[:data] || data[:items] || data
logs = [logs] if logs.is_a?(Hash)
return "No logs found for task #{task_id}." if !logs.is_a?(Array) || logs.empty?
format_task_logs(task_id, logs)
end
|
.handle_show(task_id: nil) ⇒ Object
69
70
71
72
73
74
75
76
77
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 69
def self.handle_show(task_id: nil, **)
return 'task_id is required for "show"' unless task_id
data = api_get("/api/tasks/#{task_id}")
return "API error: #{data[:error]}" if data[:error]
task = data[:data] || data
format_task_detail(task)
end
|
.handle_trigger(runner_class: nil, function: nil, payload: nil) ⇒ Object
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/legion/cli/chat/tools/manage_tasks.rb', line 92
def self.handle_trigger(runner_class: nil, function: nil, payload: nil, **)
return 'runner_class is required for "trigger"' unless runner_class
return 'function is required for "trigger"' unless function
body = { runner_class: runner_class, function: function }
body.merge!(::JSON.parse(payload, symbolize_names: true)) if payload
data = api_post('/api/tasks', body)
return "API error: #{data[:error]}" if data[:error]
result = data[:data] || data
"Task triggered successfully.\n Task ID: #{result[:task_id]}\n Runner: #{runner_class}\n Function: #{function}"
end
|