Module: Legion::Gaia::Advisory
- Extended by:
- Logging::Helper
- Defined in:
- lib/legion/gaia/advisory.rb
Class Method Summary collapse
-
.advise(caller:, conversation_id: nil, messages: nil) ⇒ Object
Fast in-memory advisory.
- .apply_suppress!(advisory, results) ⇒ Object
- .apply_tool_hints!(advisory, results) ⇒ Object
- .build_epistemic_qualifier(identity:) ⇒ Object
- .build_partner_slots(identity:) ⇒ Object
- .build_partner_system_prompt(identity:) ⇒ Object
- .drain_growth_content ⇒ Object
- .merge_observer_data!(advisory, caller) ⇒ Object
- .merge_tick_data!(advisory, tick_result) ⇒ Object
- .normalize_routing_hint(value) ⇒ Object
- .value_for(hash, key) ⇒ Object
Class Method Details
.advise(caller:, conversation_id: nil, messages: nil) ⇒ Object
Fast in-memory advisory. NEVER makes LLM calls. Returns Hash with optional keys: system_prompt, routing_hint, context_window, tool_hint, suppress, valence
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/legion/gaia/advisory.rb', line 15 def advise(caller:, conversation_id: nil, messages: nil) log.debug "advise(caller: #{caller}, conversation_id: #{conversation_id}, messages: #{}) " return nil unless Gaia.started? advisory = {} advisory[:valence] = Gaia.last_valences if Gaia.last_valences merge_tick_data!(advisory, Gaia.registry&.tick_host&.last_tick_result) merge_observer_data!(advisory, caller) identity = caller&.dig(:requested_by, :identity) partner_prompt = build_partner_system_prompt(identity: identity) if identity if partner_prompt advisory[:system_prompt] = partner_prompt log.info("[gaia] advisory partner_prompt injected identity=#{identity} length=#{partner_prompt.length}") end result = advisory.compact if result.any? log.info("GAIA advisory generated conversation_id=#{conversation_id} keys=#{result.keys.join(',')}") end result rescue StandardError => e handle_exception(e, level: :warn, operation: 'gaia.advisory.advise', conversation_id: conversation_id) {} end |
.apply_suppress!(advisory, results) ⇒ Object
64 65 66 67 68 69 70 |
# File 'lib/legion/gaia/advisory.rb', line 64 def apply_suppress!(advisory, results) suppressed = results.dig(:sensory_processing, :suppressed) return unless suppressed arr = Array(suppressed) advisory[:suppress] = arr.empty? ? nil : arr end |
.apply_tool_hints!(advisory, results) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/legion/gaia/advisory.rb', line 52 def apply_tool_hints!(advisory, results) predictions = results.dig(:prediction_engine, :predictions) return unless predictions tools = predictions.filter_map do |prediction| confidence = value_for(prediction, :confidence).to_f tool = value_for(prediction, :tool) tool if confidence >= 0.6 && tool end advisory[:tool_hint] = tools.empty? ? nil : tools end |
.build_epistemic_qualifier(identity:) ⇒ Object
152 153 154 155 156 |
# File 'lib/legion/gaia/advisory.rb', line 152 def build_epistemic_qualifier(identity:) return nil unless defined?(Legion::Gaia::VisibleGrowth) VisibleGrowth.epistemic_qualifier(identity: identity) end |
.build_partner_slots(identity:) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/legion/gaia/advisory.rb', line 127 def build_partner_slots(identity:) return nil unless defined?(Legion::Gaia::PartnerModel) slots = PartnerModel.build(identity: identity) return nil if slots.empty? lines = slots.map do |slot| domain = slot[:domain] content = slot[:content] content_str = content.is_a?(Hash) ? content.map { |k, v| "#{k}: #{v}" }.join(', ') : content.to_s "- #{domain}: #{content_str}" end "What I know about working with you:\n#{lines.join("\n")}" end |
.build_partner_system_prompt(identity:) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/legion/gaia/advisory.rb', line 105 def build_partner_system_prompt(identity:) log.unknown("[gaia] build_partner_system_prompt identity=#{identity} " \ "bond_registry_defined=#{defined?(Legion::Gaia::BondRegistry)} " \ "partner=#{defined?(Legion::Gaia::BondRegistry) && BondRegistry.partner?(identity.to_s)}") return nil unless defined?(Legion::Gaia::BondRegistry) && BondRegistry.partner?(identity.to_s) parts = ['|gaia:active|'] slots = build_partner_slots(identity: identity) parts << slots if slots log.unknown("[gaia] partner_slots count=#{slots ? 'present' : 'empty'}") growth = drain_growth_content parts << growth if growth qualifier = build_epistemic_qualifier(identity: identity) parts << qualifier if qualifier parts.join("\n\n") end |
.drain_growth_content ⇒ Object
143 144 145 146 147 148 149 150 |
# File 'lib/legion/gaia/advisory.rb', line 143 def drain_growth_content return nil unless Gaia.respond_to?(:drain_growth_frames) frames = Gaia.drain_growth_frames return nil if frames.nil? || frames.empty? frames.join("\n") end |
.merge_observer_data!(advisory, caller) ⇒ Object
72 73 74 75 76 77 78 79 |
# File 'lib/legion/gaia/advisory.rb', line 72 def merge_observer_data!(advisory, caller) identity = caller&.dig(:requested_by, :identity) return unless identity learned = AuditObserver.instance.learned_data_for(identity) advisory[:routing_hint] ||= normalize_routing_hint(learned[:routing_preference]) if learned[:routing_preference] advisory[:tool_hint] ||= learned[:tool_predictions].keys.first(5) if learned[:tool_predictions]&.any? end |
.merge_tick_data!(advisory, tick_result) ⇒ Object
41 42 43 44 45 46 47 48 49 50 |
# File 'lib/legion/gaia/advisory.rb', line 41 def merge_tick_data!(advisory, tick_result) log.debug "merge_tick_data!(#{advisory.inspect}, #{tick_result})" return unless tick_result && tick_result[:results] results = tick_result[:results] apply_tool_hints!(advisory, results) apply_suppress!(advisory, results) advisory[:routing_hint] = normalize_routing_hint(results.dig(:post_tick_reflection, :routing_preference)) advisory[:context_window] = results.dig(:memory_retrieval, :cross_conversation) end |
.normalize_routing_hint(value) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/legion/gaia/advisory.rb', line 81 def normalize_routing_hint(value) return nil if value.nil? if value.is_a?(Hash) provider = value_for(value, :provider) model = value_for(value, :model) return nil if provider.to_s.empty? && model.to_s.empty? return { provider: provider&.to_s, model: model&.to_s } end { provider: value.to_s, model: nil } end |
.value_for(hash, key) ⇒ Object
95 96 97 98 99 100 101 102 103 |
# File 'lib/legion/gaia/advisory.rb', line 95 def value_for(hash, key) return nil unless hash.respond_to?(:key?) string_key = key.to_s return hash[key] if hash.key?(key) return hash[string_key] if hash.key?(string_key) nil end |