Class: Legion::CLI::Chat::Tools::CostSummary
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
104
105
106
107
108
109
110
111
|
# File 'lib/legion/cli/chat/tools/cost_summary.rb', line 104
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_port ⇒ Object
113
114
115
116
117
118
119
|
# File 'lib/legion/cli/chat/tools/cost_summary.rb', line 113
def self.api_port
return DEFAULT_PORT unless defined?(Legion::Settings)
Legion::Settings[:api]&.dig(:port) || DEFAULT_PORT
rescue StandardError
DEFAULT_PORT
end
|
.call(action: 'summary', worker_id: nil, limit: 5) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
# File 'lib/legion/cli/chat/tools/cost_summary.rb', line 34
def self.call(action: 'summary', worker_id: nil, limit: 5)
case action.to_s
when 'top'
handle_top(limit.to_i.clamp(1, 20))
when 'worker'
return 'worker_id is required for the "worker" action.' if worker_id.nil? || worker_id.strip.empty?
handle_worker(worker_id.strip)
else
handle_summary
end
rescue Errno::ECONNREFUSED
'Legion daemon not running (cannot reach cost API).'
rescue StandardError => e
Legion::Logging.warn("CostSummary#execute failed: #{e.message}") if defined?(Legion::Logging)
"Error fetching cost data: #{e.message}"
end
|
.fetch_worker_cost(worker_id) ⇒ Object
96
97
98
99
100
101
102
|
# File 'lib/legion/cli/chat/tools/cost_summary.rb', line 96
def self.fetch_worker_cost(worker_id)
data = api_get("/api/workers/#{worker_id}/value")
data = data[:data] || data
(data[:total_cost_usd] || 0).to_f
rescue StandardError
0.0
end
|
.handle_summary ⇒ Object
52
53
54
55
56
57
58
59
60
61
62
63
|
# File 'lib/legion/cli/chat/tools/cost_summary.rb', line 52
def self.handle_summary
data = api_get('/api/costs/summary?period=month')
return "API error: #{data[:error]}" if data[:error]
data = data[:data] || data
lines = ["Cost Summary:\n"]
lines << format(' Today: $%.4f', (data[:today] || 0).to_f)
lines << format(' This Week: $%.4f', (data[:week] || 0).to_f)
lines << format(' This Month: $%.4f', (data[:month] || 0).to_f)
lines << " Workers: #{data[:workers] || 0}"
lines.join("\n")
end
|
.handle_top(limit) ⇒ Object
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
# File 'lib/legion/cli/chat/tools/cost_summary.rb', line 65
def self.handle_top(limit)
data = api_get('/api/workers')
return "API error: #{data[:error]}" if data[:error]
workers = data[:data] || data
workers = Array(workers).first(limit)
return 'No workers found.' if workers.empty?
lines = ["Top #{workers.size} Cost Consumers:\n"]
workers.each_with_index do |w, i|
id = w[:worker_id] || w[:id] || 'unknown'
cost = fetch_worker_cost(id)
lines << format(' %<rank>d. %-20<id>s $%<cost>.4f', rank: i + 1, id: id, cost: cost)
end
lines.join("\n")
end
|
.handle_worker(worker_id) ⇒ Object
82
83
84
85
86
87
88
89
90
91
92
93
94
|
# File 'lib/legion/cli/chat/tools/cost_summary.rb', line 82
def self.handle_worker(worker_id)
data = api_get("/api/workers/#{worker_id}/value")
return "API error: #{data[:error]}" if data[:error]
data = data[:data] || data
return "No cost data for worker #{worker_id}." if data.nil? || data.empty?
lines = ["Worker: #{worker_id}\n"]
data.each do |key, val|
lines << " #{key}: #{val}" unless key == :worker_id
end
lines.join("\n")
end
|