Class: Legion::CLI::Chat::Tools::MemoryStatus
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_port ⇒ Object
162
163
164
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 162
def self.api_port
(defined?(Legion::Settings) && Legion::Settings[:api] && Legion::Settings[:api][:port]) || 4567
end
|
.apollo_available? ⇒ Boolean
144
145
146
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 144
def self.apollo_available?
defined?(Legion::Data)
end
|
.apollo_stats ⇒ Object
126
127
128
129
130
131
132
133
134
135
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 126
def self.apollo_stats
return nil unless apollo_available?
data = safe_fetch('/api/apollo/stats')
return nil unless data
data[:data] || data
rescue StandardError
nil
end
|
.call(action: 'overview') ⇒ Object
19
20
21
22
23
24
25
26
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 19
def self.call(action: 'overview')
case action.to_s
when 'memories' then format_memories
when 'apollo' then format_apollo
when 'sessions' then format_sessions
else format_overview
end
end
|
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 76
def self.format_apollo
stats = apollo_stats
return 'Apollo knowledge store is not available.' unless stats
lines = ["Apollo Knowledge Store:\n"]
lines << format(' Total Entries: %<v>d', v: stats[:total] || 0)
lines << format(' Confirmed: %<v>d', v: stats[:confirmed] || 0)
lines << format(' Candidates: %<v>d', v: stats[:candidates] || 0)
lines << format(' Disputed: %<v>d', v: stats[:disputed] || 0)
lines << format(' Recent (24h): %<v>d', v: stats[:recent_24h] || 0)
lines << format(' Avg Confidence: %<v>.2f', v: stats[:avg_confidence] || 0.0)
if stats[:domains]
lines << ''
lines << ' Domains:'
stats[:domains].each do |domain, count|
lines << format(' %<d>-20s %<c>d entries', d: domain, c: count)
end
end
lines.join("\n")
end
|
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 48
def self.format_memories
require 'legion/cli/chat/memory_store'
lines = ["Persistent Memory Detail:\n"]
project = Chat::MemoryStore.list(scope: :project)
lines << ' Project Memory:'
if project.empty?
lines << ' (no entries)'
else
project.each_with_index do |entry, i|
lines << format(' %<i>d. %<e>s', i: i + 1, e: truncate(entry, 100))
end
end
lines << ''
global = Chat::MemoryStore.list(scope: :global)
lines << ' Global Memory:'
if global.empty?
lines << ' (no entries)'
else
global.each_with_index do |entry, i|
lines << format(' %<i>d. %<e>s', i: i + 1, e: truncate(entry, 100))
end
end
lines.join("\n")
end
|
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 28
def self.format_overview
lines = ["Memory & Knowledge Overview:\n"]
mem = memory_stats
lines << format(' Local Memory: %<p>d project, %<g>d global entries', p: mem[:project], g: mem[:global])
apollo = apollo_stats
lines << if apollo
format(' Apollo Store: %<t>d entries (%<c>d confirmed, %<d>d disputed)',
t: apollo[:total] || 0, c: apollo[:confirmed] || 0, d: apollo[:disputed] || 0)
else
' Apollo Store: not available'
end
sessions = session_list
lines << format(' Saved Sessions: %<c>d', c: sessions.size)
lines.join("\n")
end
|
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 99
def self.format_sessions
require 'legion/cli/chat/session_store'
sessions = Chat::SessionStore.list
return 'No saved sessions found.' if sessions.empty?
lines = [format("Saved Sessions (%<c>d):\n", c: sessions.size)]
sessions.first(10).each do |s|
age = time_ago(s[:modified])
lines << format(' %<n>-20s %<m>3d msgs %<a>s %<s>s',
n: s[:name], m: s[:message_count] || 0, a: age, s: s[:model] || '')
lines << format(' %<v>s', v: truncate(s[:summary].to_s, 80)) if s[:summary]
end
lines << format(' ... and %<n>d more', n: sessions.size - 10) if sessions.size > 10
lines.join("\n")
end
|
.memory_stats ⇒ Object
116
117
118
119
120
121
122
123
124
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 116
def self.memory_stats
require 'legion/cli/chat/memory_store'
{
project: Chat::MemoryStore.list(scope: :project).size,
global: Chat::MemoryStore.list(scope: :global).size
}
rescue StandardError
{ project: 0, global: 0 }
end
|
.safe_fetch(path) ⇒ Object
148
149
150
151
152
153
154
155
156
157
158
159
160
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 148
def self.safe_fetch(path)
require 'net/http'
uri = URI("http://127.0.0.1:#{api_port}#{path}")
http = Net::HTTP.new(uri.host, uri.port)
http.open_timeout = 2
http.read_timeout = 5
response = http.request(Net::HTTP::Get.new(uri))
return nil unless response.is_a?(Net::HTTPSuccess)
Legion::JSON.load(response.body)
rescue StandardError
nil
end
|
.session_list ⇒ Object
137
138
139
140
141
142
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 137
def self.session_list
require 'legion/cli/chat/session_store'
Chat::SessionStore.list
rescue StandardError
[]
end
|
.time_ago(time) ⇒ Object
170
171
172
173
174
175
176
177
178
179
180
181
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 170
def self.time_ago(time)
return '?' unless time
seconds = Time.now - time
if seconds < 3600
format('%<m>dm ago', m: (seconds / 60).to_i)
elsif seconds < 86_400
format('%<h>dh ago', h: (seconds / 3600).to_i)
else
format('%<d>dd ago', d: (seconds / 86_400).to_i)
end
end
|
.truncate(str, max) ⇒ Object
166
167
168
|
# File 'lib/legion/cli/chat/tools/memory_status.rb', line 166
def self.truncate(str, max)
str.length > max ? "#{str[0, max]}..." : str
end
|