hokipoki 0.5.1 ā 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/gemini_refiner +354 -0
- data/lib/generators/hive_mind/install_generator.rb +19 -9
- data/lib/generators/hokipoki/install_generator.rb +22 -33
- data/lib/hokipoki/atomic_fact_extractor.rb +1 -1
- data/lib/hokipoki/cli/gemini_connector.rb +107 -0
- data/lib/hokipoki/cli/gemini_status_monitor.rb +220 -0
- data/lib/hokipoki/configuration.rb +54 -2
- data/lib/hokipoki/vector_engine.rb +132 -3
- data/lib/hokipoki/version.rb +1 -1
- data/lib/hokipoki.rb +156 -1
- data/lib/tasks/gemini.rake +194 -0
- metadata +7 -58
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
module Hokipoki
|
|
2
|
+
module CLI
|
|
3
|
+
class GeminiStatusMonitor
|
|
4
|
+
def self.show
|
|
5
|
+
puts "šÆ Starting Gemini Refinement Dashboard..."
|
|
6
|
+
sleep(1)
|
|
7
|
+
|
|
8
|
+
loop do
|
|
9
|
+
clear_screen
|
|
10
|
+
display_header
|
|
11
|
+
display_stats
|
|
12
|
+
display_current_work
|
|
13
|
+
display_activity_log
|
|
14
|
+
display_controls
|
|
15
|
+
sleep(2)
|
|
16
|
+
end
|
|
17
|
+
rescue Interrupt
|
|
18
|
+
puts "\n\nš Gemini refinement dashboard stopped."
|
|
19
|
+
cleanup_temp_files
|
|
20
|
+
exit(0)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def self.clear_screen
|
|
26
|
+
system('clear') || system('cls')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.display_header
|
|
30
|
+
puts "āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā"
|
|
31
|
+
puts "ā š§ GEMINI VECTOR REFINEMENT DASHBOARD ā"
|
|
32
|
+
puts "āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā"
|
|
33
|
+
puts ""
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.display_stats
|
|
37
|
+
stats = fetch_refinement_stats
|
|
38
|
+
|
|
39
|
+
puts "š REFINEMENT STATS"
|
|
40
|
+
puts "āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā"
|
|
41
|
+
puts " Total Vectors: #{stats[:total_vectors]}"
|
|
42
|
+
puts " Refined: #{stats[:refined_count]} ā
"
|
|
43
|
+
puts " Pending: #{stats[:pending_count]} ā³"
|
|
44
|
+
puts " Processing Rate: #{stats[:rate]}/min"
|
|
45
|
+
puts " Last Updated: #{Time.current.strftime('%H:%M:%S')}"
|
|
46
|
+
puts ""
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.display_current_work
|
|
50
|
+
current = fetch_current_refinement
|
|
51
|
+
|
|
52
|
+
if current
|
|
53
|
+
puts "š CURRENTLY REFINING"
|
|
54
|
+
puts "āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā"
|
|
55
|
+
puts " Vector ID: #{current[:id]}"
|
|
56
|
+
puts " Content: #{truncate_text(current[:content], 60)}"
|
|
57
|
+
puts " Progress: #{progress_bar(current[:progress])}"
|
|
58
|
+
puts ""
|
|
59
|
+
else
|
|
60
|
+
puts "š¤ IDLE - Waiting for vectors to refine..."
|
|
61
|
+
puts ""
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.display_activity_log
|
|
66
|
+
puts "š RECENT ACTIVITY"
|
|
67
|
+
puts "āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā"
|
|
68
|
+
|
|
69
|
+
logs = recent_logs
|
|
70
|
+
if logs.empty?
|
|
71
|
+
puts " š No recent activity - system initializing..."
|
|
72
|
+
else
|
|
73
|
+
logs.last(5).each do |log|
|
|
74
|
+
icon = case log[:status]
|
|
75
|
+
when 'success' then 'ā
'
|
|
76
|
+
when 'error' then 'ā'
|
|
77
|
+
when 'processing' then 'š'
|
|
78
|
+
else 'š'
|
|
79
|
+
end
|
|
80
|
+
puts " #{icon} [#{log[:time]}] #{log[:message]}"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
puts ""
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.display_controls
|
|
87
|
+
puts "š® CONTROLS"
|
|
88
|
+
puts "āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā"
|
|
89
|
+
puts " Ctrl+C: Stop dashboard and exit"
|
|
90
|
+
puts " Dashboard auto-refreshes every 2 seconds"
|
|
91
|
+
puts ""
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def self.fetch_refinement_stats
|
|
95
|
+
begin
|
|
96
|
+
if defined?(Rails) && defined?(HiveMindDocument)
|
|
97
|
+
total = HiveMindDocument.count
|
|
98
|
+
refined = HiveMindDocument.where(refined: true).count
|
|
99
|
+
pending = total - refined
|
|
100
|
+
|
|
101
|
+
# Calculate processing rate from recent activity
|
|
102
|
+
rate = calculate_processing_rate
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
total_vectors: total,
|
|
106
|
+
refined_count: refined,
|
|
107
|
+
pending_count: pending,
|
|
108
|
+
rate: rate
|
|
109
|
+
}
|
|
110
|
+
else
|
|
111
|
+
{
|
|
112
|
+
total_vectors: 0,
|
|
113
|
+
refined_count: 0,
|
|
114
|
+
pending_count: 0,
|
|
115
|
+
rate: 0
|
|
116
|
+
}
|
|
117
|
+
end
|
|
118
|
+
rescue => e
|
|
119
|
+
{
|
|
120
|
+
total_vectors: "Error",
|
|
121
|
+
refined_count: "Error",
|
|
122
|
+
pending_count: "Error",
|
|
123
|
+
rate: 0
|
|
124
|
+
}
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def self.fetch_current_refinement
|
|
129
|
+
begin
|
|
130
|
+
# Check if there's a current refinement status
|
|
131
|
+
status_file = '/tmp/gemini_current_refinement.json'
|
|
132
|
+
if File.exist?(status_file)
|
|
133
|
+
current_data = JSON.parse(File.read(status_file))
|
|
134
|
+
return {
|
|
135
|
+
id: current_data['id'],
|
|
136
|
+
content: current_data['content'],
|
|
137
|
+
progress: current_data['progress'] || 0
|
|
138
|
+
}
|
|
139
|
+
end
|
|
140
|
+
rescue => e
|
|
141
|
+
# Ignore errors, just return nil
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
nil
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def self.recent_logs
|
|
148
|
+
begin
|
|
149
|
+
log_file = '/tmp/gemini_status.log'
|
|
150
|
+
return [] unless File.exist?(log_file)
|
|
151
|
+
|
|
152
|
+
File.readlines(log_file).map do |line|
|
|
153
|
+
next nil if line.strip.empty?
|
|
154
|
+
|
|
155
|
+
parts = line.strip.split(' - ', 3)
|
|
156
|
+
next nil if parts.length < 3
|
|
157
|
+
|
|
158
|
+
{
|
|
159
|
+
time: parts[0],
|
|
160
|
+
status: parts[1],
|
|
161
|
+
message: parts[2]
|
|
162
|
+
}
|
|
163
|
+
end.compact
|
|
164
|
+
rescue => e
|
|
165
|
+
[]
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def self.calculate_processing_rate
|
|
170
|
+
begin
|
|
171
|
+
logs = recent_logs
|
|
172
|
+
successful_logs = logs.select { |log| log[:status] == 'success' }
|
|
173
|
+
|
|
174
|
+
# Count successes in last 5 minutes
|
|
175
|
+
five_min_ago = Time.current - 5.minutes
|
|
176
|
+
recent_successes = successful_logs.select do |log|
|
|
177
|
+
begin
|
|
178
|
+
log_time = Time.parse(log[:time])
|
|
179
|
+
log_time > five_min_ago
|
|
180
|
+
rescue
|
|
181
|
+
false
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Convert to per-minute rate
|
|
186
|
+
(recent_successes.count * 12) / 10.0 # Approximate rate per minute
|
|
187
|
+
rescue => e
|
|
188
|
+
0
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def self.progress_bar(percent)
|
|
193
|
+
return "[āāāāāāāāāāāāāāāāāāāā] 0%" if percent.nil? || percent == 0
|
|
194
|
+
|
|
195
|
+
filled = 'ā' * (percent / 5).to_i
|
|
196
|
+
empty = 'ā' * (20 - (percent / 5).to_i)
|
|
197
|
+
"[#{filled}#{empty}] #{percent}%"
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def self.truncate_text(text, length)
|
|
201
|
+
return "" if text.nil?
|
|
202
|
+
text.length > length ? "#{text[0..length-3]}..." : text
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def self.cleanup_temp_files
|
|
206
|
+
temp_files = [
|
|
207
|
+
'/tmp/gemini_status.fifo',
|
|
208
|
+
'/tmp/gemini_refined_vectors.fifo',
|
|
209
|
+
'/tmp/gemini_current_refinement.json'
|
|
210
|
+
]
|
|
211
|
+
|
|
212
|
+
temp_files.each do |file|
|
|
213
|
+
File.delete(file) if File.exist?(file)
|
|
214
|
+
rescue
|
|
215
|
+
# Ignore cleanup errors
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
@@ -2,12 +2,64 @@
|
|
|
2
2
|
|
|
3
3
|
module Hokipoki
|
|
4
4
|
class Configuration
|
|
5
|
-
attr_accessor :
|
|
5
|
+
attr_accessor :enabled,
|
|
6
|
+
:environment,
|
|
7
|
+
:auth_type,
|
|
8
|
+
:auth_password,
|
|
9
|
+
:vector_storage,
|
|
10
|
+
:vector_db_path,
|
|
11
|
+
:parasite_mode,
|
|
12
|
+
:claude_detection,
|
|
13
|
+
:visible_output,
|
|
14
|
+
:max_context_tokens,
|
|
15
|
+
:max_response_tokens,
|
|
16
|
+
:total_token_budget,
|
|
17
|
+
:template_compression,
|
|
18
|
+
:atomic_facts,
|
|
19
|
+
:compression_target,
|
|
20
|
+
:encryption_key,
|
|
21
|
+
:vector_encryption,
|
|
22
|
+
:github_client_id,
|
|
23
|
+
:github_client_secret,
|
|
24
|
+
:debug_mode,
|
|
25
|
+
:verbose_logging,
|
|
26
|
+
:hive_mind_enabled,
|
|
6
27
|
:claude_parasite_enabled,
|
|
7
28
|
:redis_url
|
|
8
29
|
|
|
9
30
|
def initialize
|
|
10
|
-
#
|
|
31
|
+
# Core settings
|
|
32
|
+
@enabled = true
|
|
33
|
+
@environment = 'development'
|
|
34
|
+
|
|
35
|
+
# Authentication settings
|
|
36
|
+
@auth_type = 'simple'
|
|
37
|
+
@auth_password = 'Qweasd@300117903'
|
|
38
|
+
|
|
39
|
+
# Vector database settings
|
|
40
|
+
@vector_storage = :sqlite
|
|
41
|
+
@vector_db_path = File.expand_path('~/.hokipoki/vectors.db')
|
|
42
|
+
|
|
43
|
+
# Parasite settings
|
|
44
|
+
@parasite_mode = :auto_detect
|
|
45
|
+
@claude_detection = :enhanced
|
|
46
|
+
@visible_output = true
|
|
47
|
+
|
|
48
|
+
# Token budget management
|
|
49
|
+
@max_context_tokens = 1500
|
|
50
|
+
@max_response_tokens = 1000
|
|
51
|
+
@total_token_budget = 3000
|
|
52
|
+
|
|
53
|
+
# Compression settings
|
|
54
|
+
@template_compression = true
|
|
55
|
+
@atomic_facts = true
|
|
56
|
+
@compression_target = 0.75
|
|
57
|
+
|
|
58
|
+
# Development settings
|
|
59
|
+
@debug_mode = false
|
|
60
|
+
@verbose_logging = false
|
|
61
|
+
|
|
62
|
+
# Legacy settings
|
|
11
63
|
@hive_mind_enabled = false # Will be true after installation
|
|
12
64
|
@claude_parasite_enabled = true
|
|
13
65
|
@redis_url = ENV.fetch('REDIS_URL', 'redis://localhost:6379/0')
|
|
@@ -30,30 +30,53 @@ module Hokipoki
|
|
|
30
30
|
|
|
31
31
|
# Main API - Retrieve intelligent facts with template generation
|
|
32
32
|
def retrieve_facts(query, token_budget: 1500)
|
|
33
|
+
start_time = Time.current
|
|
33
34
|
$stdout.puts "š§ VECTOR ENGINE: Analyzing query intent..."
|
|
35
|
+
$stdout.puts "š° Token Budget: #{token_budget} tokens"
|
|
34
36
|
|
|
35
37
|
begin
|
|
36
38
|
# 1. Analyze query intent with multiple dimensions
|
|
39
|
+
show_progress_bar("Analyzing intent", 0.2)
|
|
37
40
|
intent = analyze_query_intent(query)
|
|
38
41
|
$stdout.puts " šÆ Intent detected: #{intent}"
|
|
39
42
|
|
|
40
43
|
# 2. Extract technical keywords
|
|
44
|
+
show_progress_bar("Extracting keywords", 0.4)
|
|
41
45
|
keywords = extract_technical_keywords(query)
|
|
42
|
-
$stdout.puts " š Keywords: #{keywords.join(', ')}"
|
|
46
|
+
$stdout.puts " š Keywords (#{keywords.length}): #{keywords.join(', ')}"
|
|
43
47
|
|
|
44
48
|
# 3. Find matching template vectors
|
|
49
|
+
show_progress_bar("Searching vectors", 0.6)
|
|
45
50
|
matching_vectors = find_matching_vectors(keywords, intent)
|
|
46
51
|
$stdout.puts " š Found #{matching_vectors.length} matching vectors"
|
|
47
52
|
|
|
48
53
|
if matching_vectors.any?
|
|
49
54
|
# 4. Generate content from templates
|
|
55
|
+
show_progress_bar("Generating content", 0.8)
|
|
50
56
|
generated_content = generate_content_from_vectors(matching_vectors, intent, keywords)
|
|
57
|
+
original_tokens = estimate_tokens(generated_content)
|
|
51
58
|
|
|
52
59
|
# 5. Apply token budget management
|
|
60
|
+
show_progress_bar("Optimizing tokens", 0.9)
|
|
53
61
|
final_content = apply_token_budget(generated_content, token_budget)
|
|
62
|
+
final_tokens = estimate_tokens(final_content)
|
|
63
|
+
|
|
64
|
+
# Calculate savings
|
|
65
|
+
tokens_saved = original_tokens - final_tokens
|
|
66
|
+
compression_percent = tokens_saved > 0 ? ((tokens_saved.to_f / original_tokens) * 100).round(1) : 0
|
|
67
|
+
|
|
68
|
+
show_progress_bar("Complete", 1.0)
|
|
69
|
+
elapsed_time = ((Time.current - start_time) * 1000).round(1)
|
|
54
70
|
|
|
55
71
|
@stats[:successful_retrievals] += 1
|
|
56
|
-
|
|
72
|
+
@stats[:total_tokens_saved] = (@stats[:total_tokens_saved] || 0) + tokens_saved
|
|
73
|
+
|
|
74
|
+
# Enhanced success display
|
|
75
|
+
$stdout.puts " ā
RETRIEVAL SUCCESSFUL!"
|
|
76
|
+
$stdout.puts " š Original: #{original_tokens} tokens ā Final: #{final_tokens} tokens"
|
|
77
|
+
$stdout.puts " š° Tokens Saved: #{tokens_saved} (#{compression_percent}% compression)"
|
|
78
|
+
$stdout.puts " ā” Processing Time: #{elapsed_time}ms"
|
|
79
|
+
$stdout.puts " š§ Vectors Used: #{matching_vectors.length}/#{@stats[:total_vectors]}"
|
|
57
80
|
|
|
58
81
|
# Learn from successful retrieval
|
|
59
82
|
learn_from_success(query, keywords, intent, final_content)
|
|
@@ -61,10 +84,20 @@ module Hokipoki
|
|
|
61
84
|
return [final_content]
|
|
62
85
|
else
|
|
63
86
|
# Fallback to template-based generation
|
|
64
|
-
|
|
87
|
+
show_progress_bar("Fallback mode", 0.8)
|
|
65
88
|
fallback_content = generate_fallback_content(query, intent, keywords)
|
|
89
|
+
fallback_tokens = estimate_tokens(fallback_content)
|
|
90
|
+
|
|
91
|
+
show_progress_bar("Complete", 1.0)
|
|
92
|
+
elapsed_time = ((Time.current - start_time) * 1000).round(1)
|
|
66
93
|
|
|
67
94
|
@stats[:failed_retrievals] += 1
|
|
95
|
+
|
|
96
|
+
$stdout.puts " ā ļø FALLBACK MODE ACTIVATED"
|
|
97
|
+
$stdout.puts " š Fallback Content: #{fallback_tokens} tokens"
|
|
98
|
+
$stdout.puts " ā” Processing Time: #{elapsed_time}ms"
|
|
99
|
+
$stdout.puts " š Recommendation: Add more vectors for better results"
|
|
100
|
+
|
|
68
101
|
return [fallback_content]
|
|
69
102
|
end
|
|
70
103
|
|
|
@@ -518,6 +551,102 @@ module Hokipoki
|
|
|
518
551
|
$stdout.puts "š¾ Database: #{@db_path}"
|
|
519
552
|
$stdout.puts "š Ready for parasitic intelligence operations"
|
|
520
553
|
end
|
|
554
|
+
|
|
555
|
+
# Enhanced progress bar with visual feedback
|
|
556
|
+
def show_progress_bar(task, progress)
|
|
557
|
+
bar_width = 20
|
|
558
|
+
filled = (progress * bar_width).round
|
|
559
|
+
empty = bar_width - filled
|
|
560
|
+
|
|
561
|
+
bar = "ā" * filled + "ā" * empty
|
|
562
|
+
percentage = (progress * 100).round(1)
|
|
563
|
+
|
|
564
|
+
$stdout.puts " š #{task.ljust(18)} [#{bar}] #{percentage}%"
|
|
565
|
+
sleep(0.1) # Brief pause for visual effect
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
# Enhanced statistics with token savings and performance metrics
|
|
569
|
+
def enhanced_statistics
|
|
570
|
+
stats = statistics
|
|
571
|
+
total_operations = @stats[:successful_retrievals] + @stats[:failed_retrievals]
|
|
572
|
+
|
|
573
|
+
avg_tokens_saved = total_operations > 0 ?
|
|
574
|
+
((@stats[:total_tokens_saved] || 0).to_f / total_operations).round(1) : 0
|
|
575
|
+
|
|
576
|
+
total_tokens_saved = @stats[:total_tokens_saved] || 0
|
|
577
|
+
|
|
578
|
+
{
|
|
579
|
+
total_vectors: stats[:total_vectors],
|
|
580
|
+
success_rate: stats[:success_rate],
|
|
581
|
+
average_compression: stats[:average_compression],
|
|
582
|
+
total_operations: total_operations,
|
|
583
|
+
successful_retrievals: @stats[:successful_retrievals],
|
|
584
|
+
failed_retrievals: @stats[:failed_retrievals],
|
|
585
|
+
total_tokens_saved: total_tokens_saved,
|
|
586
|
+
avg_tokens_saved_per_operation: avg_tokens_saved,
|
|
587
|
+
cache_size: stats[:cache_size],
|
|
588
|
+
database_size: stats[:database_size],
|
|
589
|
+
learning_patterns: stats[:learning_patterns]
|
|
590
|
+
}
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
# Display comprehensive system status with token savings
|
|
594
|
+
def display_enhanced_status
|
|
595
|
+
stats = enhanced_statistics
|
|
596
|
+
|
|
597
|
+
$stdout.puts "\nš§ ENHANCED VECTOR ENGINE STATUS"
|
|
598
|
+
$stdout.puts "=" * 50
|
|
599
|
+
$stdout.puts "š PERFORMANCE METRICS:"
|
|
600
|
+
$stdout.puts " š¢ Total Vectors: #{stats[:total_vectors]}"
|
|
601
|
+
$stdout.puts " ā
Success Rate: #{stats[:success_rate]}%"
|
|
602
|
+
$stdout.puts " šļø Avg Compression: #{stats[:average_compression]}%"
|
|
603
|
+
$stdout.puts " š Total Operations: #{stats[:total_operations]}"
|
|
604
|
+
$stdout.puts ""
|
|
605
|
+
$stdout.puts "š° TOKEN SAVINGS:"
|
|
606
|
+
$stdout.puts " š Total Saved: #{stats[:total_tokens_saved]} tokens"
|
|
607
|
+
$stdout.puts " š Avg Per Operation: #{stats[:avg_tokens_saved_per_operation]} tokens"
|
|
608
|
+
$stdout.puts " šµ Estimated Cost Savings: $#{(stats[:total_tokens_saved] * 0.00002).round(4)}"
|
|
609
|
+
$stdout.puts ""
|
|
610
|
+
$stdout.puts "š§ SYSTEM STATUS:"
|
|
611
|
+
$stdout.puts " š¾ Cache Size: #{stats[:cache_size]} entries"
|
|
612
|
+
$stdout.puts " š Database Size: #{(stats[:database_size] / 1024.0).round(2)} KB"
|
|
613
|
+
$stdout.puts " š§ Learning Patterns: #{stats[:learning_patterns]}"
|
|
614
|
+
$stdout.puts " ā” Status: #{stats[:total_operations] > 0 ? 'ACTIVE' : 'READY'}"
|
|
615
|
+
$stdout.puts "=" * 50
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
# Display real-time retrieval metrics during operation
|
|
619
|
+
def display_retrieval_progress(operation, details = {})
|
|
620
|
+
timestamp = Time.current.strftime("%H:%M:%S.%L")
|
|
621
|
+
|
|
622
|
+
case operation
|
|
623
|
+
when :start
|
|
624
|
+
$stdout.puts "\nā±ļø [#{timestamp}] RETRIEVAL SESSION STARTED"
|
|
625
|
+
$stdout.puts " šÆ Query: \"#{details[:query]}\""
|
|
626
|
+
$stdout.puts " š° Token Budget: #{details[:token_budget]} tokens"
|
|
627
|
+
|
|
628
|
+
when :intent_analysis
|
|
629
|
+
$stdout.puts " š§ [#{timestamp}] Intent Analysis: #{details[:intent]}"
|
|
630
|
+
|
|
631
|
+
when :keyword_extraction
|
|
632
|
+
$stdout.puts " š [#{timestamp}] Keywords (#{details[:count]}): #{details[:keywords]}"
|
|
633
|
+
|
|
634
|
+
when :vector_search
|
|
635
|
+
$stdout.puts " š [#{timestamp}] Vector Search: #{details[:matches]} matches found"
|
|
636
|
+
|
|
637
|
+
when :content_generation
|
|
638
|
+
$stdout.puts " āļø [#{timestamp}] Content Generation: #{details[:original_tokens]} tokens"
|
|
639
|
+
|
|
640
|
+
when :optimization
|
|
641
|
+
$stdout.puts " šÆ [#{timestamp}] Token Optimization: #{details[:final_tokens]} tokens"
|
|
642
|
+
$stdout.puts " š° Tokens Saved: #{details[:tokens_saved]} (#{details[:compression_percent]}%)"
|
|
643
|
+
|
|
644
|
+
when :complete
|
|
645
|
+
elapsed = details[:elapsed_time]
|
|
646
|
+
$stdout.puts " ā
[#{timestamp}] COMPLETE (#{elapsed}ms total)"
|
|
647
|
+
$stdout.puts " š Final Efficiency: #{details[:efficiency_score]}%"
|
|
648
|
+
end
|
|
649
|
+
end
|
|
521
650
|
end
|
|
522
651
|
end
|
|
523
652
|
|
data/lib/hokipoki/version.rb
CHANGED
data/lib/hokipoki.rb
CHANGED
|
@@ -313,6 +313,16 @@ module Hokipoki
|
|
|
313
313
|
def reset!
|
|
314
314
|
self.configuration = nil
|
|
315
315
|
end
|
|
316
|
+
|
|
317
|
+
# Quick status check command
|
|
318
|
+
def status
|
|
319
|
+
display_immediate_status
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# Quick connection status
|
|
323
|
+
def connection_status
|
|
324
|
+
display_connection_status
|
|
325
|
+
end
|
|
316
326
|
end
|
|
317
327
|
end
|
|
318
328
|
|
|
@@ -321,14 +331,159 @@ if defined?(Rails)
|
|
|
321
331
|
require_relative "hokipoki/railtie"
|
|
322
332
|
|
|
323
333
|
# Force Claude activation on Rails startup if detected
|
|
324
|
-
Rails.application
|
|
334
|
+
if Rails.application
|
|
335
|
+
Rails.application.config.after_initialize do
|
|
325
336
|
# Small delay to ensure everything is loaded
|
|
326
337
|
Thread.new do
|
|
327
338
|
sleep(1) # Give Rails time to initialize
|
|
328
339
|
if Hokipoki.claude_parasite_active?
|
|
329
340
|
$stdout.puts "š¦ FORCE ACTIVATION: Claude CLI detected during Rails startup"
|
|
330
341
|
ClaudeAutoLoader.force_load!
|
|
342
|
+
|
|
343
|
+
# Start persistent status monitor
|
|
344
|
+
Hokipoki.start_persistent_status_monitor
|
|
331
345
|
end
|
|
332
346
|
end
|
|
333
347
|
end
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# Persistent Status Monitoring System
|
|
352
|
+
module Hokipoki
|
|
353
|
+
class << self
|
|
354
|
+
def start_persistent_status_monitor
|
|
355
|
+
return if @status_monitor_running
|
|
356
|
+
|
|
357
|
+
@status_monitor_running = true
|
|
358
|
+
@last_status_display = Time.current
|
|
359
|
+
|
|
360
|
+
Thread.new do
|
|
361
|
+
loop do
|
|
362
|
+
display_connection_status if should_display_status?
|
|
363
|
+
sleep(30) # Check every 30 seconds
|
|
364
|
+
end
|
|
365
|
+
rescue => e
|
|
366
|
+
Rails.logger.error "Hokipoki status monitor error: #{e.message}" if defined?(Rails)
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
def display_connection_status
|
|
371
|
+
status = get_detailed_status
|
|
372
|
+
timestamp = Time.current.strftime("%H:%M:%S")
|
|
373
|
+
|
|
374
|
+
# Always visible status line
|
|
375
|
+
status_line = "[#{timestamp}] "
|
|
376
|
+
|
|
377
|
+
if status[:hive_mind_connected]
|
|
378
|
+
status_line += "š§ HIVE_MIND: CONNECTED | "
|
|
379
|
+
else
|
|
380
|
+
status_line += "ā ļø HIVE_MIND: DISCONNECTED | "
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
if status[:parasite_active]
|
|
384
|
+
status_line += "š¦ PARASITE: INTERCEPTING | "
|
|
385
|
+
else
|
|
386
|
+
status_line += "š PARASITE: STANDBY | "
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
if status[:token_savings_active]
|
|
390
|
+
status_line += "š° SAVINGS: #{status[:total_tokens_saved]} tokens"
|
|
391
|
+
else
|
|
392
|
+
status_line += "š° SAVINGS: READY"
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
$stdout.puts status_line
|
|
396
|
+
@last_status_display = Time.current
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
def should_display_status?
|
|
400
|
+
return true if @last_status_display.nil?
|
|
401
|
+
Time.current - @last_status_display > 60 # Every minute when Claude is active
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def get_detailed_status
|
|
405
|
+
{
|
|
406
|
+
hive_mind_connected: hive_mind_connected?,
|
|
407
|
+
parasite_active: claude_parasite_active?,
|
|
408
|
+
token_savings_active: token_savings_active?,
|
|
409
|
+
total_tokens_saved: get_total_tokens_saved,
|
|
410
|
+
rails_server_running: rails_server_running?
|
|
411
|
+
}
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
def hive_mind_connected?
|
|
415
|
+
return false unless defined?(Rails) && Rails.application
|
|
416
|
+
|
|
417
|
+
begin
|
|
418
|
+
# Check if HiveMindDocument model exists and database is accessible
|
|
419
|
+
defined?(HiveMindDocument) && HiveMindDocument.table_exists?
|
|
420
|
+
rescue => e
|
|
421
|
+
false
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
def token_savings_active?
|
|
426
|
+
return false unless defined?(VectorEngine)
|
|
427
|
+
|
|
428
|
+
begin
|
|
429
|
+
engine = VectorEngine.instance
|
|
430
|
+
stats = engine.statistics
|
|
431
|
+
stats[:successful_retrievals] > 0
|
|
432
|
+
rescue => e
|
|
433
|
+
false
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
def get_total_tokens_saved
|
|
438
|
+
return 0 unless defined?(VectorEngine)
|
|
439
|
+
|
|
440
|
+
begin
|
|
441
|
+
engine = VectorEngine.instance
|
|
442
|
+
stats = engine.enhanced_statistics
|
|
443
|
+
stats[:total_tokens_saved] || 0
|
|
444
|
+
rescue => e
|
|
445
|
+
0
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
def rails_server_running?
|
|
450
|
+
return false unless defined?(Rails)
|
|
451
|
+
|
|
452
|
+
begin
|
|
453
|
+
# Simple check - if we can access Rails application, server is likely running
|
|
454
|
+
Rails.application.present?
|
|
455
|
+
rescue => e
|
|
456
|
+
false
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
# Enhanced status for immediate display
|
|
461
|
+
def display_immediate_status
|
|
462
|
+
$stdout.puts "\nš HOKIPOKI SYSTEM STATUS"
|
|
463
|
+
$stdout.puts "=" * 50
|
|
464
|
+
|
|
465
|
+
status = get_detailed_status
|
|
466
|
+
|
|
467
|
+
$stdout.puts "š SERVICES:"
|
|
468
|
+
$stdout.puts " #{status[:rails_server_running] ? 'š¢' : 'š“'} Rails Server: #{status[:rails_server_running] ? 'RUNNING' : 'STOPPED'}"
|
|
469
|
+
$stdout.puts " #{status[:hive_mind_connected] ? 'š¢' : 'š“'} HiveMind: #{status[:hive_mind_connected] ? 'CONNECTED' : 'DISCONNECTED'}"
|
|
470
|
+
$stdout.puts " #{status[:parasite_active] ? 'š¢' : 'š“'} Parasite: #{status[:parasite_active] ? 'ACTIVE' : 'INACTIVE'}"
|
|
471
|
+
|
|
472
|
+
$stdout.puts "\nš° PERFORMANCE:"
|
|
473
|
+
$stdout.puts " šÆ Token Savings: #{status[:token_savings_active] ? 'ACTIVE' : 'READY'}"
|
|
474
|
+
$stdout.puts " š Total Saved: #{status[:total_tokens_saved]} tokens"
|
|
475
|
+
$stdout.puts " šµ Cost Savings: $#{(status[:total_tokens_saved] * 0.00002).round(4)}"
|
|
476
|
+
|
|
477
|
+
$stdout.puts "\nšÆ CLAUDE ENHANCEMENT: #{all_systems_operational?(status) ? 'MAXIMUM' : 'LIMITED'}"
|
|
478
|
+
$stdout.puts "=" * 50
|
|
479
|
+
|
|
480
|
+
status
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
private
|
|
484
|
+
|
|
485
|
+
def all_systems_operational?(status)
|
|
486
|
+
status[:hive_mind_connected] && status[:parasite_active] && status[:rails_server_running]
|
|
487
|
+
end
|
|
488
|
+
end
|
|
334
489
|
end
|