Class: Legion::Extensions::Agentic::Social::PerspectiveShifting::Helpers::ShiftingEngine
- Inherits:
-
Object
- Object
- Legion::Extensions::Agentic::Social::PerspectiveShifting::Helpers::ShiftingEngine
- Defined in:
- lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb
Instance Attribute Summary collapse
-
#perspectives ⇒ Object
readonly
Returns the value of attribute perspectives.
-
#situations ⇒ Object
readonly
Returns the value of attribute situations.
Instance Method Summary collapse
- #add_perspective(name:, type: :stakeholder, priorities: [], empathy: Constants::DEFAULT_EMPATHY, bias: nil, expertise_domains: []) ⇒ Object
- #add_situation(content:) ⇒ Object
- #blind_spots(situation_id:) ⇒ Object
- #coverage_score(situation_id:) ⇒ Object
- #dominant_view(situation_id:) ⇒ Object
- #generate_view(situation_id:, perspective_id:, valence: 0.0, concerns: [], opportunities: [], confidence: 0.5) ⇒ Object
-
#initialize ⇒ ShiftingEngine
constructor
A new instance of ShiftingEngine.
- #most_divergent_pair(situation_id:) ⇒ Object
- #perspective_agreement(situation_id:) ⇒ Object
- #synthesize(situation_id:) ⇒ Object
- #to_h ⇒ Object
- #views_for_situation(situation_id:) ⇒ Object
Constructor Details
#initialize ⇒ ShiftingEngine
Returns a new instance of ShiftingEngine.
14 15 16 17 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 14 def initialize @perspectives = {} @situations = {} end |
Instance Attribute Details
#perspectives ⇒ Object (readonly)
Returns the value of attribute perspectives.
12 13 14 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 12 def perspectives @perspectives end |
#situations ⇒ Object (readonly)
Returns the value of attribute situations.
12 13 14 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 12 def situations @situations end |
Instance Method Details
#add_perspective(name:, type: :stakeholder, priorities: [], empathy: Constants::DEFAULT_EMPATHY, bias: nil, expertise_domains: []) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 19 def add_perspective(name:, type: :stakeholder, priorities: [], empathy: Constants::DEFAULT_EMPATHY, bias: nil, expertise_domains: []) return { error: :too_many_perspectives } if @perspectives.size >= Constants::MAX_PERSPECTIVES return { error: :invalid_type } unless Constants::PERSPECTIVE_TYPES.include?(type) sym_priorities = Array(priorities).map(&:to_sym) invalid = sym_priorities - Constants::PRIORITY_TYPES return { error: :invalid_priorities, invalid: invalid } unless invalid.empty? p = Perspective.new( name: name, perspective_type: type, priorities: priorities, expertise_domains: expertise_domains, empathy_level: empathy, bias_toward: bias ) @perspectives[p.id] = p p end |
#add_situation(content:) ⇒ Object
40 41 42 43 44 45 46 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 40 def add_situation(content:) return { error: :too_many_situations } if @situations.size >= Constants::MAX_SITUATIONS id = SecureRandom.uuid @situations[id] = { id: id, content: content, views: [], created_at: Time.now.utc } @situations[id] end |
#blind_spots(situation_id:) ⇒ Object
89 90 91 92 93 94 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 89 def blind_spots(situation_id:) views = views_for_situation(situation_id: situation_id) applied_ids = views.map(&:perspective_id).uniq applied_types = applied_ids.filter_map { |pid| @perspectives[pid]&.perspective_type }.uniq Constants::PERSPECTIVE_TYPES - applied_types end |
#coverage_score(situation_id:) ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 96 def coverage_score(situation_id:) views = views_for_situation(situation_id: situation_id) return 0.0 if @perspectives.empty? applied_count = views.map(&:perspective_id).uniq.size (applied_count.to_f / @perspectives.size).clamp(0.0, 1.0).round(10) end |
#dominant_view(situation_id:) ⇒ Object
104 105 106 107 108 109 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 104 def dominant_view(situation_id:) views = views_for_situation(situation_id: situation_id) return nil if views.empty? views.max_by(&:confidence) end |
#generate_view(situation_id:, perspective_id:, valence: 0.0, concerns: [], opportunities: [], confidence: 0.5) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 48 def generate_view(situation_id:, perspective_id:, valence: 0.0, concerns: [], opportunities: [], confidence: 0.5) situation = @situations[situation_id] perspective = @perspectives[perspective_id] return { error: :situation_not_found } unless situation return { error: :perspective_not_found } unless perspective return { error: :too_many_views } if situation[:views].size >= Constants::MAX_VIEWS_PER_SITUATION view = PerspectiveView.new( situation_id: situation_id, perspective_id: perspective_id, valence: valence, concerns: concerns, opportunities: opportunities, confidence: confidence ) situation[:views] << view view end |
#most_divergent_pair(situation_id:) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 136 def most_divergent_pair(situation_id:) views = views_for_situation(situation_id: situation_id) return nil if views.size < 2 max_diff = -1.0 pair = nil views.combination(2) do |a, b| diff = (a.valence - b.valence).abs if diff > max_diff max_diff = diff pair = [a, b] end end pair end |
#perspective_agreement(situation_id:) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 76 def perspective_agreement(situation_id:) views = views_for_situation(situation_id: situation_id) return 0.0 if views.size < Constants::MIN_PERSPECTIVES_FOR_SYNTHESIS valences = views.map(&:valence) mean = valences.sum / valences.size.to_f variance = valences.sum { |v| (v - mean)**2 } / valences.size.to_f std_dev = Math.sqrt(variance) # Agreement is inverse of normalized std_dev (max std_dev is 1.0 for symmetric ±1 distribution) (1.0 - std_dev).clamp(0.0, 1.0).round(10) end |
#synthesize(situation_id:) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 111 def synthesize(situation_id:) views = views_for_situation(situation_id: situation_id) return { error: :insufficient_views } if views.size < Constants::MIN_PERSPECTIVES_FOR_SYNTHESIS total_confidence = views.sum(&:confidence) return { error: :zero_confidence } if total_confidence.zero? weighted_valence = views.sum { |v| v.valence * v.confidence } / total_confidence all_concerns = views.flat_map(&:concerns).uniq all_opportunities = views.flat_map(&:opportunities).uniq agreement = perspective_agreement(situation_id: situation_id) { situation_id: situation_id, weighted_valence: weighted_valence.round(10), concerns: all_concerns, opportunities: all_opportunities, agreement: agreement.round(10), agreement_label: Constants.agreement_label(agreement), view_count: views.size, coverage_score: coverage_score(situation_id: situation_id), coverage_label: Constants.coverage_label(coverage_score(situation_id: situation_id)) } end |
#to_h ⇒ Object
154 155 156 157 158 159 160 161 162 163 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 154 def to_h { perspective_count: @perspectives.size, situation_count: @situations.size, perspectives: @perspectives.values.map(&:to_h), situations: @situations.values.map do |s| s.merge(views: s[:views].map(&:to_h)) end } end |
#views_for_situation(situation_id:) ⇒ Object
69 70 71 72 73 74 |
# File 'lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb', line 69 def views_for_situation(situation_id:) situation = @situations[situation_id] return [] unless situation situation[:views] end |