Class: Aidp::Harness::StatusDisplay

Inherits:
Object
  • Object
show all
Includes:
MessageDisplay
Defined in:
lib/aidp/harness/status_display.rb

Overview

Real-time status updates and monitoring interface

Defined Under Namespace

Classes: AlertManager, DisplayAnimator, MetricsCalculator, StatusFormatter

Constant Summary

Constants included from MessageDisplay

MessageDisplay::COLOR_MAP, MessageDisplay::CRITICAL_TYPES

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from MessageDisplay

#display_message, included, #message_display_prompt, #quiet_mode?

Constructor Details

#initialize(provider_manager = nil, metrics_manager = nil, circuit_breaker_manager = nil, error_logger = nil, prompt: TTY::Prompt.new) ⇒ StatusDisplay

Returns a new instance of StatusDisplay.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/aidp/harness/status_display.rb', line 23

def initialize(provider_manager = nil, metrics_manager = nil, circuit_breaker_manager = nil, error_logger = nil, prompt: TTY::Prompt.new)
  @provider_manager = provider_manager
  @metrics_manager = metrics_manager
  @circuit_breaker_manager = circuit_breaker_manager
  @error_logger = error_logger
  @prompt = prompt
  @cursor = TTY::Cursor

  @start_time = nil
  @current_step = nil
  @current_provider = nil
  @current_model = nil
  @status_thread = nil
  @running = false
  @display_mode = :compact
  @update_interval = 2
  @last_update = Time.now
  @status_data = {}
  @internal_status_data = @status_data # Alias for testability
  @performance_metrics = {}
  @error_summary = {}
  @provider_status = {}
  @model_status = {}
  @circuit_breaker_status = {}
  @token_usage = {}
  @rate_limit_status = {}
  @recovery_status = {}
  @user_feedback_status = {}
  @work_completion_status = {}
  @configuration = {}
  @display_config = initialize_display_config
  @status_formatter = StatusFormatter.new
  @metrics_calculator = MetricsCalculator.new
  @alert_manager = AlertManager.new
  @display_animator = DisplayAnimator.new
end

Instance Attribute Details

#alert_managerObject (readonly)

Returns the value of attribute alert_manager.



19
20
21
# File 'lib/aidp/harness/status_display.rb', line 19

def alert_manager
  @alert_manager
end

#circuit_breaker_statusObject

Returns the value of attribute circuit_breaker_status.



16
17
18
# File 'lib/aidp/harness/status_display.rb', line 16

def circuit_breaker_status
  @circuit_breaker_status
end

#current_modelObject

Expose state for testability



13
14
15
# File 'lib/aidp/harness/status_display.rb', line 13

def current_model
  @current_model
end

#current_providerObject

Expose state for testability



13
14
15
# File 'lib/aidp/harness/status_display.rb', line 13

def current_provider
  @current_provider
end

#current_stepObject

Expose state for testability



13
14
15
# File 'lib/aidp/harness/status_display.rb', line 13

def current_step
  @current_step
end

#display_animatorObject (readonly)

Returns the value of attribute display_animator.



19
20
21
# File 'lib/aidp/harness/status_display.rb', line 19

def display_animator
  @display_animator
end

#display_configObject

Returns the value of attribute display_config.



18
19
20
# File 'lib/aidp/harness/status_display.rb', line 18

def display_config
  @display_config
end

#error_summaryObject

Returns the value of attribute error_summary.



15
16
17
# File 'lib/aidp/harness/status_display.rb', line 15

def error_summary
  @error_summary
end

#internal_status_dataObject

Internal status hash (separate from computed status_data method)



21
22
23
# File 'lib/aidp/harness/status_display.rb', line 21

def internal_status_data
  @internal_status_data
end

#metrics_calculatorObject (readonly)

Returns the value of attribute metrics_calculator.



19
20
21
# File 'lib/aidp/harness/status_display.rb', line 19

def metrics_calculator
  @metrics_calculator
end

#performance_metricsObject

Returns the value of attribute performance_metrics.



15
16
17
# File 'lib/aidp/harness/status_display.rb', line 15

def performance_metrics
  @performance_metrics
end

#provider_statusObject

Returns the value of attribute provider_status.



16
17
18
# File 'lib/aidp/harness/status_display.rb', line 16

def provider_status
  @provider_status
end

#rate_limit_statusObject

Returns the value of attribute rate_limit_status.



17
18
19
# File 'lib/aidp/harness/status_display.rb', line 17

def rate_limit_status
  @rate_limit_status
end

#recovery_statusObject

Returns the value of attribute recovery_status.



17
18
19
# File 'lib/aidp/harness/status_display.rb', line 17

def recovery_status
  @recovery_status
end

#runningObject

Returns the value of attribute running.



14
15
16
# File 'lib/aidp/harness/status_display.rb', line 14

def running
  @running
end

#start_timeObject

Returns the value of attribute start_time.



14
15
16
# File 'lib/aidp/harness/status_display.rb', line 14

def start_time
  @start_time
end

#status_formatterObject (readonly)

Returns the value of attribute status_formatter.



19
20
21
# File 'lib/aidp/harness/status_display.rb', line 19

def status_formatter
  @status_formatter
end

#token_usageObject

Returns the value of attribute token_usage.



16
17
18
# File 'lib/aidp/harness/status_display.rb', line 16

def token_usage
  @token_usage
end

#user_feedback_statusObject

Returns the value of attribute user_feedback_status.



17
18
19
# File 'lib/aidp/harness/status_display.rb', line 17

def user_feedback_status
  @user_feedback_status
end

#work_completion_statusObject

Returns the value of attribute work_completion_status.



18
19
20
# File 'lib/aidp/harness/status_display.rb', line 18

def work_completion_status
  @work_completion_status
end

Instance Method Details

#cleanupObject

Cleanup display



268
269
270
271
# File 'lib/aidp/harness/status_display.rb', line 268

def cleanup
  stop_status_updates
  clear_display
end

#configure_display(config) ⇒ Object

Configure display settings



203
204
205
# File 'lib/aidp/harness/status_display.rb', line 203

def configure_display(config)
  @display_config.merge!(config)
end

#display_mode(mode = nil) ⇒ Object

Get or set display mode



183
184
185
186
187
188
189
190
# File 'lib/aidp/harness/status_display.rb', line 183

def display_mode(mode = nil)
  if mode.nil?
    @display_mode
  else
    @display_mode = mode
    @display_config[:mode] = mode
  end
end

#export_status_data(format = :json) ⇒ Object

Export status data



291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/aidp/harness/status_display.rb', line 291

def export_status_data(format = :json)
  case format
  when :json
    JSON.pretty_generate(status_data)
  when :yaml
    status_data.to_yaml
  when :text
    format_status_as_text
  else
    raise ArgumentError, "Unsupported format: #{format}"
  end
end

#show_completion_status(duration, steps_completed, total_steps) ⇒ Object

Show completion status



251
252
253
254
255
256
257
# File 'lib/aidp/harness/status_display.rb', line 251

def show_completion_status(duration, steps_completed, total_steps)
  clear_display
  display_message("\n✅ Harness COMPLETED", type: :success)
  display_message("   Duration: #{format_duration(duration)}", type: :info)
  display_message("   Steps completed: #{steps_completed}/#{total_steps}", type: :info)
  display_message("   All workflows finished successfully!", type: :success)
end

#show_error_status(error_message) ⇒ Object

Show error status



260
261
262
263
264
265
# File 'lib/aidp/harness/status_display.rb', line 260

def show_error_status(error_message)
  clear_display
  display_message("\n❌ Harness ERROR", type: :error)
  display_message("   Error: #{error_message}", type: :error)
  display_message("   Check logs for details", type: :info)
end

#show_paused_statusObject

Show paused status



208
209
210
211
212
213
214
215
216
# File 'lib/aidp/harness/status_display.rb', line 208

def show_paused_status
  clear_display
  display_message("\n⏸️  Harness PAUSED", type: :warning)
  display_message("   Press 'r' to resume, 's' to stop", type: :info)
  display_message("   Current step: #{@current_step}", type: :info) if @current_step
  display_message("   Current provider: #{@current_provider}", type: :info) if @current_provider
  display_message("   Current model: #{@current_model}", type: :info) if @current_model
  display_message("   Duration: #{format_duration(Time.now - @start_time)}", type: :info) if @start_time
end

#show_rate_limit_wait(reset_time) ⇒ Object

Show rate limit wait



233
234
235
236
237
238
239
240
# File 'lib/aidp/harness/status_display.rb', line 233

def show_rate_limit_wait(reset_time)
  clear_display
  remaining = reset_time - Time.now
  display_message("\n🚫 Rate limit reached", type: :error)
  display_message("   Waiting for reset at #{reset_time.strftime("%H:%M:%S")}", type: :info)
  display_message("   Remaining: #{format_duration(remaining)}", type: :info)
  display_message("   Press Ctrl+C to cancel", type: :info)
end

#show_resumed_statusObject

Show resumed status



219
220
221
222
223
# File 'lib/aidp/harness/status_display.rb', line 219

def show_resumed_status
  clear_display
  display_message("\n▶️  Harness RESUMED", type: :success)
  display_message("   Continuing execution...", type: :info)
end

#show_stopped_statusObject

Show stopped status



226
227
228
229
230
# File 'lib/aidp/harness/status_display.rb', line 226

def show_stopped_status
  clear_display
  display_message("\n⏹️  Harness STOPPED", type: :error)
  display_message("   Execution terminated by user", type: :info)
end

#start_status_updates(display_mode = :compact, async_updates: true) ⇒ Object

Start real-time status updates



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/aidp/harness/status_display.rb', line 61

def start_status_updates(display_mode = :compact, async_updates: true)
  return if @running

  @running = true
  @start_time = Time.now
  @display_mode = display_mode
  @last_update = Time.now

  if async_updates
    begin
      require "concurrent"
      @status_future = Concurrent::Future.execute do
        while @running
          begin
            collect_status_data
            display_status
            check_alerts
            sleep(@update_interval)
          rescue => e
            handle_display_error(e)
          end
        end
      end
    rescue LoadError
      # Fallback: perform single synchronous update if concurrent not available
      collect_status_data
      display_status
    end
  else
    # Synchronous single update mode (useful for tests)
    collect_status_data
    display_status
  end
end

#status_dataObject

Get comprehensive status data



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/aidp/harness/status_display.rb', line 274

def status_data
  {
    basic_info: basic_status,
    provider_info: provider_status,
    performance_info: performance_status,
    error_info: error_status,
    circuit_breaker_info: circuit_breaker_status,
    token_info: token_status,
    rate_limit_info: rate_limit_status,
    recovery_info: recovery_status,
    user_feedback_info: user_feedback_status,
    work_completion_info: work_completion_status,
    alerts: alerts
  }
end

#stop_status_updatesObject

Stop status updates



97
98
99
100
101
# File 'lib/aidp/harness/status_display.rb', line 97

def stop_status_updates
  @running = false
  @status_future&.wait(5)
  clear_display
end

#update_current_model(_provider_name, model_name) ⇒ Object

Update current model



118
119
120
121
122
# File 'lib/aidp/harness/status_display.rb', line 118

def update_current_model(_provider_name, model_name)
  @current_model = model_name
  @status_data[:current_model] = model_name
  @status_data[:model_switch_time] = Time.now
end

#update_current_provider(provider_name) ⇒ Object

Update current provider



111
112
113
114
115
# File 'lib/aidp/harness/status_display.rb', line 111

def update_current_provider(provider_name)
  @current_provider = provider_name
  @status_data[:current_provider] = provider_name
  @status_data[:provider_switch_time] = Time.now
end

#update_current_step(step_name) ⇒ Object

Update current step



104
105
106
107
108
# File 'lib/aidp/harness/status_display.rb', line 104

def update_current_step(step_name)
  @current_step = step_name
  @status_data[:current_step] = step_name
  @status_data[:step_start_time] = Time.now
end

#update_error_summary(error_summary) ⇒ Object

Update error summary



177
178
179
180
# File 'lib/aidp/harness/status_display.rb', line 177

def update_error_summary(error_summary)
  @error_summary.merge!(error_summary)
  @error_summary[:last_updated] = Time.now
end

#update_interval(interval = nil) ⇒ Object

Get or set update interval



193
194
195
196
197
198
199
200
# File 'lib/aidp/harness/status_display.rb', line 193

def update_interval(interval = nil)
  if interval.nil?
    @update_interval
  else
    @update_interval = interval
    @display_config[:update_interval] = interval
  end
end

#update_performance_metrics(metrics) ⇒ Object

Update performance metrics



171
172
173
174
# File 'lib/aidp/harness/status_display.rb', line 171

def update_performance_metrics(metrics)
  @performance_metrics.merge!(metrics)
  @performance_metrics[:last_updated] = Time.now
end

#update_rate_limit_countdown(remaining_seconds) ⇒ Object

Update rate limit countdown



243
244
245
246
247
248
# File 'lib/aidp/harness/status_display.rb', line 243

def update_rate_limit_countdown(remaining_seconds)
  clear_display
  display_message("\n🚫 Rate limit - waiting...", type: :warning)
  display_message("   Resets in: #{format_duration(remaining_seconds)}", type: :info)
  display_message("   Press Ctrl+C to cancel", type: :info)
end

#update_rate_limit_status(provider, model, rate_limit_info) ⇒ Object

Update rate limit status



135
136
137
138
139
140
141
142
143
144
145
# File 'lib/aidp/harness/status_display.rb', line 135

def update_rate_limit_status(provider, model, rate_limit_info)
  @rate_limit_status[provider] ||= {}
  @rate_limit_status[provider][model] = {
    rate_limited: true,
    reset_time: rate_limit_info[:reset_time],
    retry_after: rate_limit_info[:retry_after],
    quota_remaining: rate_limit_info[:quota_remaining],
    quota_limit: rate_limit_info[:quota_limit],
    last_updated: Time.now
  }
end

#update_recovery_status(recovery_type, status, details = {}) ⇒ Object

Update recovery status



148
149
150
151
152
153
154
# File 'lib/aidp/harness/status_display.rb', line 148

def update_recovery_status(recovery_type, status, details = {})
  @recovery_status[recovery_type] = {
    status: status,
    details: details,
    last_updated: Time.now
  }
end

#update_token_usage(provider, model, tokens_used, tokens_remaining = nil) ⇒ Object

Update token usage



125
126
127
128
129
130
131
132
# File 'lib/aidp/harness/status_display.rb', line 125

def update_token_usage(provider, model, tokens_used, tokens_remaining = nil)
  @token_usage[provider] ||= {}
  @token_usage[provider][model] = {
    used: tokens_used,
    remaining: tokens_remaining,
    last_updated: Time.now
  }
end

#update_user_feedback_status(feedback_type, status, details = {}) ⇒ Object

Update user feedback status



157
158
159
160
161
162
163
# File 'lib/aidp/harness/status_display.rb', line 157

def update_user_feedback_status(feedback_type, status, details = {})
  @user_feedback_status[feedback_type] = {
    status: status,
    details: details,
    last_updated: Time.now
  }
end

#update_work_completion_status(completion_info) ⇒ Object

Update work completion status



166
167
168
# File 'lib/aidp/harness/status_display.rb', line 166

def update_work_completion_status(completion_info)
  @work_completion_status = completion_info.merge(last_updated: Time.now)
end