Class: Legion::Extensions::Agentic::Integration::Context::Helpers::ContextManager

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb

Constant Summary

Constants included from Constants

Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::DEFAULT_FAMILIARITY, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::FAMILIARITY_ALPHA, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::FRAME_DECAY, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::FRAME_LABELS, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::FRAME_STRENGTH_FLOOR, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::MAX_CUES_PER_FRAME, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::MAX_FRAMES, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::MAX_FRAME_STACK, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::MAX_HISTORY, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::RELEVANCE_THRESHOLD, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::SWITCH_COOLDOWN, Legion::Extensions::Agentic::Integration::Context::Helpers::Constants::SWITCH_COST

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeContextManager

Returns a new instance of ContextManager.



14
15
16
17
18
19
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 14

def initialize
  @frames         = []
  @active_stack   = []
  @switch_history = []
  @last_switch_at = nil
end

Instance Attribute Details

#active_stackObject (readonly)

Returns the value of attribute active_stack.



12
13
14
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 12

def active_stack
  @active_stack
end

#framesObject (readonly)

Returns the value of attribute frames.



12
13
14
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 12

def frames
  @frames
end

#switch_historyObject (readonly)

Returns the value of attribute switch_history.



12
13
14
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 12

def switch_history
  @switch_history
end

Instance Method Details

#activate(frame_id) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 28

def activate(frame_id)
  frame = find(frame_id)
  return nil unless frame

  previous = current_frame
  cost = 0.0

  if previous && previous.id != frame_id
    cost = compute_switch_cost(previous, frame)
    previous.deactivate
    record_switch(from: previous, to: frame, cost: cost)
  end

  @active_stack.reject! { |f| f.id == frame_id }
  @active_stack.push(frame)
  @active_stack.shift while @active_stack.size > MAX_FRAME_STACK
  frame.activate
  { frame: frame, switch_cost: cost }
end

#auto_switch(input_cues) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 59

def auto_switch(input_cues)
  candidates = detect_context(input_cues)
  return nil if candidates.empty?

  best = candidates.first
  current = current_frame

  return nil if current && current.id == best[:frame].id

  activate(best[:frame].id)
end

#create_frame(name:, domain: :general, cues: []) ⇒ Object



21
22
23
24
25
26
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 21

def create_frame(name:, domain: :general, cues: [])
  frame = Frame.new(name: name, domain: domain, cues: cues)
  @frames << frame
  trim_frames
  frame
end

#current_frameObject



48
49
50
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 48

def current_frame
  @active_stack.last
end

#decay_allObject



83
84
85
86
87
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 83

def decay_all
  @frames.each(&:decay)
  @frames.reject!(&:stale?)
  @active_stack.reject!(&:stale?)
end

#detect_context(input_cues) ⇒ Object



52
53
54
55
56
57
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 52

def detect_context(input_cues)
  scored = @frames.map { |f| [f, f.match_score(input_cues)] }
  scored.select! { |_, score| score >= RELEVANCE_THRESHOLD }
  scored.sort_by! { |_, score| -score }
  scored.map { |f, score| { frame: f, relevance: score } }
end

#find(frame_id) ⇒ Object



71
72
73
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 71

def find(frame_id)
  @frames.find { |f| f.id == frame_id }
end

#find_by_name(name) ⇒ Object



75
76
77
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 75

def find_by_name(name)
  @frames.select { |f| f.name == name }
end

#in_domain(domain) ⇒ Object



79
80
81
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 79

def in_domain(domain)
  @frames.select { |f| f.domain == domain }
end

#remove(frame_id) ⇒ Object



89
90
91
92
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 89

def remove(frame_id)
  @frames.reject! { |f| f.id == frame_id }
  @active_stack.reject! { |f| f.id == frame_id }
end

#switch_cost_averageObject



94
95
96
97
98
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 94

def switch_cost_average
  return 0.0 if @switch_history.empty?

  @switch_history.sum { |s| s[:cost] }.to_f / @switch_history.size
end

#to_hObject



100
101
102
103
104
105
106
107
108
109
# File 'lib/legion/extensions/agentic/integration/context/helpers/context_manager.rb', line 100

def to_h
  {
    frame_count:     @frames.size,
    active_frame:    current_frame&.name,
    stack_depth:     @active_stack.size,
    switch_count:    @switch_history.size,
    avg_switch_cost: switch_cost_average.round(4),
    by_domain:       @frames.group_by(&:domain).transform_values(&:size)
  }
end