Module: Legion::MCP::StateTracker
- Extended by:
- Logging::Helper
- Defined in:
- lib/legion/mcp/state_tracker.rb
Constant Summary collapse
- MAX_SNAPSHOTS =
50
Class Method Summary collapse
- .collect_extension_count ⇒ Object
- .collect_observer_stats ⇒ Object
- .collect_pattern_count ⇒ Object
- .collect_state ⇒ Object
- .compute_diff(baseline, current) ⇒ Object
- .diff(since:) ⇒ Object
- .find_baseline(since_time) ⇒ Object
- .parse_time(value) ⇒ Object
- .reset! ⇒ Object
- .snapshot ⇒ Object
- .snapshots ⇒ Object
- .snapshots_mutex ⇒ Object
Class Method Details
.collect_extension_count ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/legion/mcp/state_tracker.rb', line 70 def collect_extension_count return 0 unless defined?(Legion::Extensions) extensions = if Legion::Extensions.respond_to?(:extensions) Legion::Extensions.extensions else Legion::Extensions.instance_variable_get(:@extensions) end extensions&.size || 0 rescue StandardError => e handle_exception(e, level: :debug, operation: 'legion.mcp.state_tracker.collect_extension_count') 0 end |
.collect_observer_stats ⇒ Object
51 52 53 54 55 56 57 58 59 |
# File 'lib/legion/mcp/state_tracker.rb', line 51 def collect_observer_stats return {} unless defined?(Observer) stats = Observer.stats { total_calls: stats[:total_calls], tool_count: stats[:tool_count], failure_rate: stats[:failure_rate] } rescue StandardError => e handle_exception(e, level: :debug, operation: 'legion.mcp.state_tracker.collect_observer_stats') {} end |
.collect_pattern_count ⇒ Object
61 62 63 64 65 66 67 68 |
# File 'lib/legion/mcp/state_tracker.rb', line 61 def collect_pattern_count return 0 unless defined?(PatternStore) PatternStore.respond_to?(:size) ? PatternStore.size : 0 rescue StandardError => e handle_exception(e, level: :debug, operation: 'legion.mcp.state_tracker.collect_pattern_count') 0 end |
.collect_state ⇒ Object
42 43 44 45 46 47 48 49 |
# File 'lib/legion/mcp/state_tracker.rb', line 42 def collect_state { tool_count: Server.tool_registry.size, observer_stats: collect_observer_stats, pattern_count: collect_pattern_count, extensions: collect_extension_count } end |
.compute_diff(baseline, current) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/legion/mcp/state_tracker.rb', line 84 def compute_diff(baseline, current) changes = {} all_keys = (baseline.keys | current.keys).uniq all_keys.each do |key| old_val = baseline[key] new_val = current[key] next if old_val == new_val if old_val.is_a?(Hash) && new_val.is_a?(Hash) nested = compute_diff(old_val, new_val) changes[key] = nested unless nested.empty? else changes[key] = { before: old_val, after: new_val } end end changes end |
.diff(since:) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/legion/mcp/state_tracker.rb', line 25 def diff(since:) log.info('Starting legion.mcp.state_tracker.diff') since_time = parse_time(since) return { error: 'invalid timestamp' } unless since_time baseline = find_baseline(since_time) current = collect_state if baseline.nil? return { full_state: current, reason: 'no baseline found for given timestamp', timestamp: Time.now.iso8601 } end changes = compute_diff(baseline[:state], current) { changes: changes, since: since_time.iso8601, timestamp: Time.now.iso8601 } end |
.find_baseline(since_time) ⇒ Object
105 106 107 108 109 |
# File 'lib/legion/mcp/state_tracker.rb', line 105 def find_baseline(since_time) snapshots_mutex.synchronize do snapshots.reverse.find { |s| s[:timestamp] <= since_time } end end |
.parse_time(value) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/legion/mcp/state_tracker.rb', line 111 def parse_time(value) case value when Time value when String Time.parse(value) when Numeric Time.at(value) end rescue ArgumentError => e handle_exception(e, level: :debug, operation: 'legion.mcp.state_tracker.parse_time') nil end |
.reset! ⇒ Object
133 134 135 |
# File 'lib/legion/mcp/state_tracker.rb', line 133 def reset! snapshots_mutex.synchronize { snapshots.clear } end |
.snapshot ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/legion/mcp/state_tracker.rb', line 12 def snapshot log.info('Starting legion.mcp.state_tracker.snapshot') state = collect_state = Time.now.floor snapshots_mutex.synchronize do snapshots << { state: state, timestamp: } snapshots.shift if snapshots.size > MAX_SNAPSHOTS end { state: state, timestamp: .iso8601 } end |
.snapshots ⇒ Object
125 126 127 |
# File 'lib/legion/mcp/state_tracker.rb', line 125 def snapshots @snapshots ||= [] end |
.snapshots_mutex ⇒ Object
129 130 131 |
# File 'lib/legion/mcp/state_tracker.rb', line 129 def snapshots_mutex @snapshots_mutex ||= Mutex.new end |