Class: Legion::CLI::Chat::Tools::Reflect
Constant Summary
collapse
- DEFAULT_PORT =
4567
- DEFAULT_HOST =
'127.0.0.1'
<<~PROMPT
Extract discrete, reusable knowledge entries from the following text.
Each entry should be a standalone fact, pattern, decision, or procedure
that would be useful in future conversations.
Rules:
- One entry per line, prefixed with "- "
- Be specific and actionable, not vague
- Include context (file paths, module names, patterns)
- Skip trivial observations
- Maximum 5 entries
Return ONLY the entries, no headers or commentary.
PROMPT
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
140
141
142
143
144
145
146
|
# File 'lib/legion/cli/chat/tools/reflect.rb', line 140
def self.api_port
return DEFAULT_PORT unless defined?(Legion::Settings)
Legion::Settings[:api]&.dig(:port) || DEFAULT_PORT
rescue StandardError
DEFAULT_PORT
end
|
.call(text:, domain: nil) ⇒ Object
49
50
51
52
53
54
55
56
57
58
|
# File 'lib/legion/cli/chat/tools/reflect.rb', line 49
def self.call(text:, domain: nil)
entries = (text)
return 'No actionable knowledge found to reflect on.' if entries.empty?
results = ingest_entries(entries, domain)
format_results(entries, results)
rescue StandardError => e
Legion::Logging.warn("Reflect#execute failed: #{e.message}") if defined?(Legion::Logging)
"Error during reflection: #{e.message}"
end
|
60
61
62
63
64
65
66
67
68
69
70
|
# File 'lib/legion/cli/chat/tools/reflect.rb', line 60
def self.(text)
return [text] unless llm_available?
response = Legion::LLM.chat(
message: "#{EXTRACTION_PROMPT}\n\nText:\n#{text}",
caller: { requested_by: { type: :system, identity: 'legion:internal:cli:reflect' } }
)
parse_entries((response))
rescue StandardError
[text]
end
|
72
73
74
75
76
77
78
79
80
|
# File 'lib/legion/cli/chat/tools/reflect.rb', line 72
def self.(response)
if response.is_a?(Hash)
(response[:response] || response[:content] || response['response'] || response['content']).to_s
elsif response.respond_to?(:content)
response.content.to_s
else
response.to_s
end
end
|
128
129
130
131
132
133
134
|
# File 'lib/legion/cli/chat/tools/reflect.rb', line 128
def self.format_results(entries, results)
lines = ["Reflected on #{entries.size} knowledge entries:\n"]
entries.each_with_index { |e, i| lines << " #{i + 1}. #{e}" }
lines << ''
lines << "Saved: #{results[:apollo]} to Apollo, #{results[:memory]} to memory"
lines.join("\n")
end
|
.ingest_entries(entries, domain) ⇒ Object
91
92
93
94
95
96
97
98
|
# File 'lib/legion/cli/chat/tools/reflect.rb', line 91
def self.ingest_entries(entries, domain)
results = { apollo: 0, memory: 0 }
entries.each do |entry|
results[:apollo] += 1 if ingest_to_apollo(entry, domain)
results[:memory] += 1 if save_to_memory(entry)
end
results
end
|
.ingest_to_apollo(content, domain) ⇒ Object
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/legion/cli/chat/tools/reflect.rb', line 100
def self.ingest_to_apollo(content, domain)
uri = URI("http://#{DEFAULT_HOST}:#{api_port}/api/apollo/ingest")
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({
content: content,
content_type: 'observation',
tags: %w[reflection auto-learned],
source_agent: 'chat',
source_channel: 'reflection',
knowledge_domain: domain
})
response = http.request(req)
response.is_a?(Net::HTTPSuccess)
rescue StandardError
false
end
|
.llm_available? ⇒ Boolean
136
137
138
|
# File 'lib/legion/cli/chat/tools/reflect.rb', line 136
def self.llm_available?
defined?(Legion::LLM) && Legion::LLM.respond_to?(:chat)
end
|
.parse_entries(content) ⇒ Object
82
83
84
85
86
87
88
89
|
# File 'lib/legion/cli/chat/tools/reflect.rb', line 82
def self.parse_entries(content)
content.lines
.map(&:strip)
.select { |line| line.start_with?('- ') }
.map { |line| line.sub(/\A- /, '').strip }
.reject(&:empty?)
.first(5)
end
|
.save_to_memory(entry) ⇒ Object
120
121
122
123
124
125
126
|
# File 'lib/legion/cli/chat/tools/reflect.rb', line 120
def self.save_to_memory(entry)
require 'legion/cli/chat/memory_store'
MemoryStore.add(entry, scope: :project)
true
rescue StandardError
false
end
|