Module: Legion::Extensions::Apollo::Helpers::Writeback
- Defined in:
- lib/legion/extensions/apollo/helpers/writeback.rb
Constant Summary collapse
- RESEARCH_TOOLS =
%w[read_file search_files search_content run_command].freeze
- MAX_CONTENT_LENGTH =
4000- MIN_CONTENT_LENGTH =
50
Class Method Summary collapse
- .build_payload(request:, response:, source_channel: nil) ⇒ Object
- .content_hash(content) ⇒ Object
- .derive_tags(query) ⇒ Object
- .evaluate_and_route(request:, response:, enrichments: {}) ⇒ Object
- .extract_identity(request) ⇒ Object
- .extract_tool_calls(response, enrichments) ⇒ Object
- .extract_user_query(request) ⇒ Object
- .min_content_length ⇒ Object
- .publish_to_transport(payload, has_embedding: false) ⇒ Object
- .response_content(response) ⇒ Object
- .route_payload(payload) ⇒ Object
- .should_capture?(_request, response, enrichments) ⇒ Boolean
- .write_directly(payload) ⇒ Object
- .writeback_enabled? ⇒ Boolean
Class Method Details
.build_payload(request:, response:, source_channel: nil) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 43 def build_payload(request:, response:, source_channel: nil) content = response_content(response) caller_identity = extract_identity(request) user_query = extract_user_query(request) = (user_query) { content: content[0...MAX_CONTENT_LENGTH], content_type: 'observation', tags: Helpers::TagNormalizer.normalize_all(), source_agent: response.respond_to?(:model) ? response.model : 'unknown', source_channel: "#{source_channel || 'pipeline'}_synthesis", submitted_by: caller_identity, submitted_from: Socket.gethostname, knowledge_domain: nil, content_hash: content_hash(content) } end |
.content_hash(content) ⇒ Object
108 109 110 111 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 108 def content_hash(content) normalized = content.to_s.strip.downcase.gsub(/\s+/, ' ') Digest::MD5.hexdigest(normalized) end |
.derive_tags(query) ⇒ Object
144 145 146 147 148 149 150 151 152 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 144 def (query) stop_words = %w[a an the is are was were be been being have has had do does did will would shall should may might can could of in to for on with at by from as into about between how what when where why who which this that these those it its and or but not] words = query.to_s.downcase.gsub(/[^a-z0-9\s]/, '').split words.reject { |w| stop_words.include?(w) || w.length < 3 } .uniq .first(5) end |
.evaluate_and_route(request:, response:, enrichments: {}) ⇒ Object
17 18 19 20 21 22 23 24 25 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 17 def evaluate_and_route(request:, response:, enrichments: {}) return unless writeback_enabled? return unless should_capture?(request, response, enrichments) payload = build_payload(request: request, response: response) route_payload(payload) rescue StandardError => e Legion::Logging.warn("apollo writeback failed: #{e.}") if defined?(Legion::Logging) end |
.extract_identity(request) ⇒ Object
120 121 122 123 124 125 126 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 120 def extract_identity(request) return 'unknown' unless request.respond_to?(:caller) && request.caller.is_a?(Hash) request.caller.dig(:requested_by, :identity) || 'unknown' rescue StandardError 'unknown' end |
.extract_tool_calls(response, enrichments) ⇒ Object
137 138 139 140 141 142 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 137 def extract_tool_calls(response, enrichments) calls = [] calls += Array(response.tool_calls) if response.respond_to?(:tool_calls) calls += Array(enrichments['tool_calls']) if enrichments['tool_calls'] calls.uniq { |tc| tc[:name] || tc['name'] } end |
.extract_user_query(request) ⇒ Object
128 129 130 131 132 133 134 135 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 128 def extract_user_query(request) return '' unless request.respond_to?(:messages) user_msgs = Array(request.).select { |m| m[:role] == 'user' || m['role'] == 'user' } (user_msgs.last || {})[:content] || '' rescue StandardError '' end |
.min_content_length ⇒ Object
102 103 104 105 106 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 102 def min_content_length Legion::Settings.dig(:apollo, :writeback, :min_content_length) || MIN_CONTENT_LENGTH rescue StandardError MIN_CONTENT_LENGTH end |
.publish_to_transport(payload, has_embedding: false) ⇒ Object
86 87 88 89 90 91 92 93 94 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 86 def publish_to_transport(payload, has_embedding: false) return unless defined?(Legion::Transport) Transport::Messages::Writeback.new( **payload, has_embedding: ).publish rescue StandardError => e Legion::Logging.warn("apollo writeback publish failed: #{e.}") if defined?(Legion::Logging) end |
.response_content(response) ⇒ Object
113 114 115 116 117 118 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 113 def response_content(response) msg = response.respond_to?(:message) ? response. : nil return nil unless msg.is_a?(Hash) msg[:content] || msg['content'] end |
.route_payload(payload) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 62 def route_payload(payload) = Helpers::Capability. can_write = Helpers::Capability.can_write? if result = Legion::LLM::Embeddings.generate(text: payload[:content]) vector = result.is_a?(Hash) ? result[:vector] : result payload[:embedding] = vector.is_a?(Array) && vector.any? ? vector : Array.new(1024, 0.0) end if can_write && write_directly(payload) else publish_to_transport(payload, has_embedding: ) end end |
.should_capture?(_request, response, enrichments) ⇒ Boolean
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 27 def should_capture?(_request, response, enrichments) content = response_content(response) return false if content.nil? || content.length < min_content_length tool_calls = extract_tool_calls(response, enrichments) research_calls = tool_calls.select { |tc| RESEARCH_TOOLS.include?(tc[:name] || tc['name']) } return false if research_calls.empty? apollo_results = enrichments['rag_context:apollo_results'] return true if apollo_results.nil? || (apollo_results[:count] || 0).zero? # Apollo had results — only capture if LLM also did additional research research_calls.any? end |
.write_directly(payload) ⇒ Object
79 80 81 82 83 84 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 79 def write_directly(payload) Runners::Knowledge.handle_ingest(**payload) rescue StandardError => e Legion::Logging.warn("apollo direct write failed, falling back to transport: #{e.}") if defined?(Legion::Logging) publish_to_transport(payload, has_embedding: !payload[:embedding].nil?) end |
.writeback_enabled? ⇒ Boolean
96 97 98 99 100 |
# File 'lib/legion/extensions/apollo/helpers/writeback.rb', line 96 def writeback_enabled? Legion::Settings.dig(:apollo, :writeback, :enabled) != false rescue StandardError true end |