hokipoki 0.6.0 โ†’ 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed4df53728ff68f28ed85980d403bf9d88334ab640b9c21d4dba872829809828
4
- data.tar.gz: 4df94c5a23b270a76594dbdc2b7388c7e72c50c5923f28c0c52de442dd1c3d92
3
+ metadata.gz: 4fdce824f42ae5123c16881e6750eea924cff8b6b2cd498f4329050411994d18
4
+ data.tar.gz: 8b150ca5b979b06b4265db8c0cdb873045dece1d85b39ac440b436919a096bd0
5
5
  SHA512:
6
- metadata.gz: f8303c679e50d81757ae0333a223ed6ffe3101422a4dcee69617cfbcb26ed110181e9030f0a304ede648748562b6e4c51c9dcf13a3508c8f99a077767d91f4ce
7
- data.tar.gz: 81bb03656528100088575379a7246c468cb61a56318c46d614ced1c4fca0a50d2d6531f20faf9fd70a1b25e5c4158fad023074f9a6c2ee88366176a3973cde9e
6
+ metadata.gz: '018c838374788cbd86af2fafe917568925b59cf6e137026c35326b4f2d137a4fe585939367c5c7935ac1e5719bd026a8ebe909742be45a45cf9e28a23b303bf9'
7
+ data.tar.gz: 216d2b1790a380a03e68c7895e450442679c00cb766226c3dc5c84d3cc0f442c2e18e4332d76a8463e7c5ae2438e753bce140767ef7bd722a91892a16973507e
@@ -0,0 +1,354 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Gemini Vector Refinement Engine
4
+ # This script runs in a separate terminal and handles vector refinement
5
+
6
+ require 'json'
7
+ require 'net/http'
8
+ require 'uri'
9
+ require 'time'
10
+
11
+ class GeminiRefiner
12
+ def initialize
13
+ @base_url = 'http://localhost:3000'
14
+ @template_file = '/tmp/gemini_refinement_template.json'
15
+ @status_file = '/tmp/gemini_status.log'
16
+ @current_refinement_file = '/tmp/gemini_current_refinement.json'
17
+ @batch_size = 10
18
+ @sleep_interval = 5
19
+ @refinement_count = 0
20
+ @start_time = Time.now
21
+
22
+ setup_logging
23
+ load_template
24
+ end
25
+
26
+ def start
27
+ display_startup_banner
28
+ check_connectivity
29
+
30
+ log_status('info', 'Gemini refinement engine started')
31
+ puts "๐Ÿ”„ Starting refinement loop..."
32
+ puts ""
33
+
34
+ main_refinement_loop
35
+ rescue Interrupt
36
+ puts "\n\n๐Ÿ‘‹ Gemini refinement engine shutting down..."
37
+ cleanup
38
+ exit(0)
39
+ rescue => e
40
+ log_status('error', "Critical error: #{e.message}")
41
+ puts "โŒ Critical error: #{e.message}"
42
+ exit(1)
43
+ end
44
+
45
+ private
46
+
47
+ def setup_logging
48
+ # Initialize log file
49
+ File.write(@status_file, "")
50
+ end
51
+
52
+ def load_template
53
+ if File.exist?(@template_file)
54
+ @template = JSON.parse(File.read(@template_file))
55
+ puts "๐Ÿ“‹ Template loaded from #{@template_file}"
56
+ else
57
+ puts "โš ๏ธ Template file not found, using defaults"
58
+ @template = default_template
59
+ end
60
+ end
61
+
62
+ def display_startup_banner
63
+ puts "โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—"
64
+ puts "โ•‘ ๐Ÿง  GEMINI REFINEMENT ENGINE โ•‘"
65
+ puts "โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
66
+ puts ""
67
+ puts "๐ŸŽฏ Configuration:"
68
+ puts " Endpoint: #{@base_url}/api/gemini"
69
+ puts " Batch Size: #{@batch_size} vectors"
70
+ puts " Interval: #{@sleep_interval} seconds"
71
+ puts " Template: #{@template_file}"
72
+ puts ""
73
+ end
74
+
75
+ def check_connectivity
76
+ puts "๐Ÿ“ก Testing connectivity..."
77
+
78
+ begin
79
+ uri = URI("#{@base_url}/api/gemini/health_check")
80
+ response = Net::HTTP.get_response(uri)
81
+
82
+ if response.code == '200'
83
+ puts " โœ… API endpoint: Connected"
84
+ else
85
+ puts " โš ๏ธ API endpoint: #{response.code} #{response.message}"
86
+ end
87
+ rescue => e
88
+ puts " โŒ API endpoint: Connection failed (#{e.message})"
89
+ puts ""
90
+ puts "๐Ÿ”ง Troubleshooting:"
91
+ puts " - Make sure Rails server is running: rails server"
92
+ puts " - Check if the forge_generator app is accessible"
93
+ puts ""
94
+ exit(1)
95
+ end
96
+
97
+ # Test Gemini CLI (mock for now)
98
+ if has_gemini_cli?
99
+ puts " โœ… Gemini CLI: Available"
100
+ else
101
+ puts " โš ๏ธ Gemini CLI: Using mock refinement"
102
+ end
103
+
104
+ puts ""
105
+ end
106
+
107
+ def main_refinement_loop
108
+ loop do
109
+ begin
110
+ # Fetch unrefined vectors
111
+ vectors = fetch_unrefined_vectors
112
+
113
+ if vectors && vectors.any?
114
+ puts "๐Ÿ“ฅ Received #{vectors.count} vectors for refinement"
115
+
116
+ # Process each vector
117
+ refined_vectors = []
118
+ vectors.each_with_index do |vector, index|
119
+ refined = refine_vector(vector, index + 1, vectors.count)
120
+ refined_vectors << refined if refined
121
+ end
122
+
123
+ # Submit refined vectors
124
+ if refined_vectors.any?
125
+ submit_refined_vectors(refined_vectors)
126
+ @refinement_count += refined_vectors.count
127
+
128
+ # Update stats display
129
+ display_current_stats
130
+ end
131
+ else
132
+ puts "๐Ÿ’ค No vectors to refine... waiting #{@sleep_interval}s"
133
+ clear_current_refinement
134
+ end
135
+
136
+ sleep(@sleep_interval)
137
+
138
+ rescue => e
139
+ log_status('error', "Refinement loop error: #{e.message}")
140
+ puts "โŒ Error in refinement loop: #{e.message}"
141
+ puts " Retrying in #{@sleep_interval} seconds..."
142
+ sleep(@sleep_interval)
143
+ end
144
+ end
145
+ end
146
+
147
+ def fetch_unrefined_vectors
148
+ uri = URI("#{@base_url}/api/gemini/unrefined_vectors?batch_size=#{@batch_size}")
149
+ response = Net::HTTP.get_response(uri)
150
+
151
+ if response.code == '200'
152
+ data = JSON.parse(response.body)
153
+ data['vectors']
154
+ else
155
+ log_status('error', "Failed to fetch vectors: #{response.code}")
156
+ nil
157
+ end
158
+ rescue => e
159
+ log_status('error', "Network error fetching vectors: #{e.message}")
160
+ nil
161
+ end
162
+
163
+ def refine_vector(vector, current_index, total_count)
164
+ vector_id = vector['id']
165
+ content = vector['content']
166
+
167
+ puts "๐Ÿ”„ [#{current_index}/#{total_count}] Refining vector ##{vector_id}..."
168
+
169
+ # Update current refinement status
170
+ update_current_refinement(vector_id, content, current_index, total_count)
171
+
172
+ # Perform refinement (mock implementation for now)
173
+ refined_data = perform_gemini_refinement(content)
174
+
175
+ log_status('success', "Refined vector ##{vector_id} (#{refined_data[:keywords]&.count || 0} keywords)")
176
+
177
+ {
178
+ 'id' => vector_id,
179
+ 'chunks' => refined_data[:chunks],
180
+ 'keywords' => refined_data[:keywords],
181
+ 'generators' => refined_data[:generators]
182
+ }
183
+ rescue => e
184
+ log_status('error', "Failed to refine vector ##{vector_id}: #{e.message}")
185
+ puts " โŒ Error refining vector ##{vector_id}: #{e.message}"
186
+ nil
187
+ end
188
+
189
+ def perform_gemini_refinement(content)
190
+ # Mock refinement implementation
191
+ # In real implementation, this would call Gemini API
192
+
193
+ words = content.split
194
+ chunks = []
195
+ keywords = []
196
+
197
+ # Simple chunking (50 words max)
198
+ words.each_slice(50) do |chunk_words|
199
+ chunk_text = chunk_words.join(' ')
200
+ chunks << chunk_text
201
+
202
+ # Extract keywords (simple implementation)
203
+ chunk_keywords = extract_keywords(chunk_text)
204
+ keywords.concat(chunk_keywords)
205
+ end
206
+
207
+ # Create generators
208
+ generators = create_generators(keywords, chunks)
209
+
210
+ {
211
+ chunks: chunks,
212
+ keywords: keywords.uniq,
213
+ generators: generators
214
+ }
215
+ end
216
+
217
+ def extract_keywords(text)
218
+ # Simple keyword extraction (mock)
219
+ words = text.downcase.split(/\W+/)
220
+
221
+ # Filter meaningful words (longer than 3 chars, not common words)
222
+ common_words = %w[the and for are but not you all can had her was one our out day get has him how its may new now old see two way who boy did man its can all]
223
+
224
+ meaningful_words = words.select do |word|
225
+ word.length > 3 && !common_words.include?(word)
226
+ end
227
+
228
+ # Return top 5 most frequent
229
+ meaningful_words.tally.sort_by { |_, count| -count }.first(5).map(&:first)
230
+ end
231
+
232
+ def create_generators(keywords, chunks)
233
+ generators = []
234
+
235
+ # Create one generator per chunk with its keywords
236
+ chunks.each_with_index do |chunk, index|
237
+ chunk_keywords = keywords.sample(3) # Use 3 random keywords
238
+
239
+ generators << {
240
+ 'trigger' => chunk_keywords,
241
+ 'template' => "Based on the context: #{chunk.truncate(100)}",
242
+ 'confidence' => 0.7 + (rand * 0.3) # Random confidence 0.7-1.0
243
+ }
244
+ end
245
+
246
+ generators
247
+ end
248
+
249
+ def submit_refined_vectors(refined_vectors)
250
+ uri = URI("#{@base_url}/api/gemini/submit_refined")
251
+
252
+ http = Net::HTTP.new(uri.host, uri.port)
253
+ request = Net::HTTP::Post.new(uri)
254
+ request['Content-Type'] = 'application/json'
255
+ request.body = { vectors: refined_vectors }.to_json
256
+
257
+ response = http.request(request)
258
+
259
+ if response.code == '200'
260
+ puts "โœ… Successfully submitted #{refined_vectors.count} refined vectors"
261
+ log_status('success', "Submitted #{refined_vectors.count} refined vectors")
262
+ else
263
+ puts "โš ๏ธ Submission warning: #{response.code} #{response.message}"
264
+ log_status('error', "Submission failed: #{response.code}")
265
+ end
266
+ rescue => e
267
+ puts "โŒ Failed to submit refined vectors: #{e.message}"
268
+ log_status('error', "Submission error: #{e.message}")
269
+ end
270
+
271
+ def update_current_refinement(vector_id, content, current, total)
272
+ progress = ((current.to_f / total) * 100).round
273
+
274
+ current_data = {
275
+ 'id' => vector_id,
276
+ 'content' => content,
277
+ 'progress' => progress,
278
+ 'current' => current,
279
+ 'total' => total,
280
+ 'updated_at' => Time.now.iso8601
281
+ }
282
+
283
+ File.write(@current_refinement_file, current_data.to_json)
284
+ rescue
285
+ # Ignore file write errors
286
+ end
287
+
288
+ def clear_current_refinement
289
+ File.delete(@current_refinement_file) if File.exist?(@current_refinement_file)
290
+ rescue
291
+ # Ignore file delete errors
292
+ end
293
+
294
+ def display_current_stats
295
+ runtime = Time.now - @start_time
296
+ rate = @refinement_count / (runtime / 60.0) # per minute
297
+
298
+ puts ""
299
+ puts "๐Ÿ“Š Session Stats:"
300
+ puts " Refined: #{@refinement_count} vectors"
301
+ puts " Runtime: #{(runtime / 60).round(1)} minutes"
302
+ puts " Rate: #{rate.round(1)}/min"
303
+ puts ""
304
+ end
305
+
306
+ def log_status(level, message)
307
+ timestamp = Time.now.strftime('%H:%M:%S')
308
+ log_entry = "#{timestamp} - #{level} - #{message}"
309
+
310
+ File.open(@status_file, 'a') do |f|
311
+ f.puts log_entry
312
+ end
313
+ rescue
314
+ # Ignore logging errors
315
+ end
316
+
317
+ def has_gemini_cli?
318
+ system('which gemini > /dev/null 2>&1') ||
319
+ system('which google-ai > /dev/null 2>&1') ||
320
+ ENV['GEMINI_API_KEY'] || ENV['GOOGLE_API_KEY']
321
+ end
322
+
323
+ def default_template
324
+ {
325
+ 'mode' => 'vector_refinement',
326
+ 'instructions' => {
327
+ 'primary' => 'Refine each vector into atomic facts with keywords',
328
+ 'chunking' => {
329
+ 'max_words' => 50,
330
+ 'create_generators' => true,
331
+ 'keyword_density' => '3-5 per chunk'
332
+ }
333
+ }
334
+ }
335
+ end
336
+
337
+ def cleanup
338
+ clear_current_refinement
339
+ log_status('info', 'Gemini refinement engine stopped')
340
+ end
341
+ end
342
+
343
+ # String truncate method
344
+ class String
345
+ def truncate(length)
346
+ self.length > length ? "#{self[0..length-3]}..." : self
347
+ end unless method_defined?(:truncate)
348
+ end
349
+
350
+ # Start the refiner
351
+ if __FILE__ == $0
352
+ refiner = GeminiRefiner.new
353
+ refiner.start
354
+ end
@@ -0,0 +1,107 @@
1
+ module Hokipoki
2
+ module CLI
3
+ class GeminiConnector
4
+ def self.start
5
+ puts "๐Ÿš€ Starting Gemini Vector Refinement Engine..."
6
+ puts ""
7
+
8
+ # 1. Create refinement template
9
+ create_refinement_template
10
+
11
+ # 2. Create communication pipes
12
+ setup_communication_pipes
13
+
14
+ # 3. Open new terminal with Gemini
15
+ terminal_cmd = build_terminal_command
16
+ puts "๐Ÿ“ก Opening Gemini terminal..."
17
+ system(terminal_cmd)
18
+
19
+ # 4. Start monitoring dashboard in current terminal
20
+ sleep(2) # Give terminal time to open
21
+ puts "๐ŸŽฏ Starting refinement dashboard..."
22
+ puts ""
23
+ show_refinement_dashboard
24
+ end
25
+
26
+ private
27
+
28
+ def self.create_refinement_template
29
+ template = {
30
+ mode: "vector_refinement",
31
+ instructions: {
32
+ primary: "Refine each vector into atomic facts with keywords",
33
+ chunking: {
34
+ max_words: 50,
35
+ create_generators: true,
36
+ keyword_density: "3-5 per chunk"
37
+ },
38
+ output_format: {
39
+ chunks: "array of atomic facts",
40
+ keywords: "array of trigger words",
41
+ generators: "keyword โ†’ response patterns"
42
+ }
43
+ },
44
+ endpoint: "http://localhost:3000/api/gemini/unrefined_vectors",
45
+ submit_endpoint: "http://localhost:3000/api/gemini/submit_refined",
46
+ batch_size: 10,
47
+ interval: 5
48
+ }
49
+
50
+ File.write('/tmp/gemini_refinement_template.json', template.to_json)
51
+ end
52
+
53
+ def self.setup_communication_pipes
54
+ # Create named pipes for communication
55
+ system("mkfifo /tmp/gemini_status.fifo 2>/dev/null || true")
56
+ system("mkfifo /tmp/gemini_refined_vectors.fifo 2>/dev/null || true")
57
+
58
+ # Create status file
59
+ File.write('/tmp/gemini_status.log', "")
60
+ end
61
+
62
+ def self.build_terminal_command
63
+ # Get the gem's bin directory
64
+ gem_bin_path = File.expand_path('../../../../bin/gemini_refiner', __FILE__)
65
+
66
+ gemini_script = <<~SCRIPT
67
+ clear
68
+ echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
69
+ echo " ๐Ÿง  GEMINI VECTOR REFINEMENT ENGINE"
70
+ echo "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
71
+ echo ""
72
+ echo "๐Ÿ“ก Connecting to HiveMind at http://localhost:3000"
73
+ echo "๐ŸŽฏ Template: /tmp/gemini_refinement_template.json"
74
+ echo "โšก Starting refinement loop..."
75
+ echo ""
76
+
77
+ # Run the gemini refiner script
78
+ #{gem_bin_path}
79
+ SCRIPT
80
+
81
+ # Write script to temp file
82
+ script_path = '/tmp/start_gemini_refiner.sh'
83
+ File.write(script_path, gemini_script)
84
+ system("chmod +x #{script_path}")
85
+
86
+ # Open in new terminal (works on macOS and Linux)
87
+ if RUBY_PLATFORM =~ /darwin/
88
+ # macOS
89
+ "osascript -e 'tell app \"Terminal\" to do script \"#{script_path}\"'"
90
+ elsif ENV['DISPLAY']
91
+ # Linux with GUI
92
+ "gnome-terminal -- bash -c \"#{script_path}; exec bash\" || xterm -e \"#{script_path}; exec bash\""
93
+ else
94
+ # Fallback - run in background and show message
95
+ puts "โš ๏ธ GUI terminal not available. Run this in a separate terminal:"
96
+ puts " #{script_path}"
97
+ return "echo 'Run #{script_path} in separate terminal'"
98
+ end
99
+ end
100
+
101
+ def self.show_refinement_dashboard
102
+ require_relative 'gemini_status_monitor'
103
+ GeminiStatusMonitor.show
104
+ end
105
+ end
106
+ end
107
+ end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Hokipoki
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -0,0 +1,194 @@
1
+ namespace :gemini do
2
+ desc "Start Gemini vector refinement engine in new terminal"
3
+ task :start => :environment do
4
+ require_relative '../hokipoki/cli/gemini_connector'
5
+
6
+ puts "๐Ÿš€ GEMINI VECTOR REFINEMENT SYSTEM"
7
+ puts "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
8
+ puts ""
9
+ puts "๐Ÿ“‹ Pre-flight checks:"
10
+
11
+ # Check if Rails is available
12
+ if defined?(Rails)
13
+ puts " โœ… Rails environment loaded"
14
+ else
15
+ puts " โŒ Rails not available"
16
+ exit(1)
17
+ end
18
+
19
+ # Check if HiveMindDocument model exists
20
+ if defined?(HiveMindDocument)
21
+ doc_count = HiveMindDocument.count rescue 0
22
+ puts " โœ… HiveMindDocument available (#{doc_count} vectors)"
23
+ else
24
+ puts " โš ๏ธ HiveMindDocument not available (will work but no data)"
25
+ end
26
+
27
+ # Check if Rails server is running
28
+ begin
29
+ require 'net/http'
30
+ response = Net::HTTP.get_response(URI('http://localhost:3000/'))
31
+ puts " โœ… Rails server running on port 3000"
32
+ rescue
33
+ puts " โš ๏ธ Rails server not detected on port 3000"
34
+ puts " Starting Rails server in background..."
35
+
36
+ # Try to start Rails server in background
37
+ Thread.new do
38
+ system("cd #{Rails.root} && rails server -d")
39
+ end
40
+ sleep(3)
41
+ end
42
+
43
+ puts ""
44
+ puts "๐ŸŽฏ Starting Gemini refinement system..."
45
+ puts ""
46
+
47
+ # Start the Gemini connector
48
+ Hokipoki::CLI::GeminiConnector.start
49
+ end
50
+
51
+ desc "Show Gemini refinement status"
52
+ task :status => :environment do
53
+ require_relative '../hokipoki/cli/gemini_status_monitor'
54
+
55
+ puts "๐Ÿ” GEMINI REFINEMENT STATUS"
56
+ puts "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
57
+ puts ""
58
+
59
+ # Show current status without the interactive dashboard
60
+ stats = fetch_quick_stats
61
+
62
+ puts "๐Ÿ“Š Quick Stats:"
63
+ puts " Total Vectors: #{stats[:total_vectors]}"
64
+ puts " Refined: #{stats[:refined_count]} โœ…"
65
+ puts " Pending: #{stats[:pending_count]} โณ"
66
+ puts ""
67
+
68
+ # Check if Gemini process is running
69
+ gemini_running = system('pgrep -f "gemini_refiner" > /dev/null')
70
+ if gemini_running
71
+ puts "๐Ÿ”„ Gemini refiner: RUNNING"
72
+ else
73
+ puts "๐Ÿ’ค Gemini refiner: STOPPED"
74
+ puts ""
75
+ puts " To start: rails gemini:start"
76
+ end
77
+
78
+ puts ""
79
+ puts " For live dashboard: rails gemini:start"
80
+ end
81
+
82
+ desc "Stop Gemini refinement engine"
83
+ task :stop => :environment do
84
+ puts "๐Ÿ›‘ Stopping Gemini refinement engine..."
85
+
86
+ # Kill Gemini processes
87
+ system('pkill -f "gemini_refiner"')
88
+
89
+ # Clean up temp files
90
+ temp_files = [
91
+ '/tmp/gemini_status.fifo',
92
+ '/tmp/gemini_refined_vectors.fifo',
93
+ '/tmp/gemini_current_refinement.json',
94
+ '/tmp/gemini_refinement_template.json',
95
+ '/tmp/gemini_status.log',
96
+ '/tmp/start_gemini_refiner.sh'
97
+ ]
98
+
99
+ temp_files.each do |file|
100
+ File.delete(file) if File.exist?(file)
101
+ rescue
102
+ # Ignore cleanup errors
103
+ end
104
+
105
+ puts "โœ… Gemini refinement engine stopped"
106
+ puts "๐Ÿงน Temporary files cleaned up"
107
+ end
108
+
109
+ desc "Test Gemini API connection"
110
+ task :test => :environment do
111
+ puts "๐Ÿงช GEMINI API CONNECTION TEST"
112
+ puts "โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
113
+ puts ""
114
+
115
+ # Test basic connectivity
116
+ begin
117
+ require 'net/http'
118
+ require 'json'
119
+
120
+ # Test unrefined vectors endpoint
121
+ puts "๐Ÿ“ก Testing API endpoints..."
122
+
123
+ uri = URI('http://localhost:3000/api/gemini/unrefined_vectors')
124
+ response = Net::HTTP.get_response(uri)
125
+
126
+ if response.code == '200'
127
+ puts " โœ… Unrefined vectors endpoint: OK"
128
+ data = JSON.parse(response.body)
129
+ puts " Found #{data['vectors']&.count || 0} vectors"
130
+ else
131
+ puts " โŒ Unrefined vectors endpoint: FAILED (#{response.code})"
132
+ end
133
+
134
+ rescue => e
135
+ puts " โŒ API test failed: #{e.message}"
136
+ puts ""
137
+ puts " ๐Ÿ”ง Troubleshooting:"
138
+ puts " - Make sure Rails server is running: rails server"
139
+ puts " - Check if API routes are configured"
140
+ end
141
+
142
+ # Test Gemini CLI availability
143
+ puts ""
144
+ puts "๐Ÿ” Testing Gemini CLI..."
145
+
146
+ if system('which gemini > /dev/null 2>&1')
147
+ puts " โœ… Gemini CLI found"
148
+
149
+ # Test Gemini API key
150
+ if ENV['GEMINI_API_KEY'] || ENV['GOOGLE_API_KEY']
151
+ puts " โœ… API key configured"
152
+ else
153
+ puts " โš ๏ธ API key not found in environment"
154
+ puts " Set GEMINI_API_KEY or GOOGLE_API_KEY"
155
+ end
156
+ else
157
+ puts " โŒ Gemini CLI not found"
158
+ puts " Install with: npm install -g @google/generative-ai"
159
+ end
160
+
161
+ puts ""
162
+ puts "๐ŸŽฏ Test complete!"
163
+ end
164
+
165
+ private
166
+
167
+ def fetch_quick_stats
168
+ begin
169
+ if defined?(HiveMindDocument)
170
+ total = HiveMindDocument.count
171
+ refined = HiveMindDocument.where(refined: true).count
172
+ pending = total - refined
173
+
174
+ {
175
+ total_vectors: total,
176
+ refined_count: refined,
177
+ pending_count: pending
178
+ }
179
+ else
180
+ {
181
+ total_vectors: 0,
182
+ refined_count: 0,
183
+ pending_count: 0
184
+ }
185
+ end
186
+ rescue => e
187
+ {
188
+ total_vectors: "Error",
189
+ refined_count: "Error",
190
+ pending_count: "Error"
191
+ }
192
+ end
193
+ end
194
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hokipoki
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rails Utilities
@@ -209,11 +209,13 @@ description: A collection of utilities and enhancements for Rails applications i
209
209
  database optimizations, background processing helpers, and developer tools.
210
210
  email:
211
211
  - utilities@example.com
212
- executables: []
212
+ executables:
213
+ - gemini_refiner
213
214
  extensions: []
214
215
  extra_rdoc_files: []
215
216
  files:
216
217
  - LICENSE
218
+ - bin/gemini_refiner
217
219
  - lib/generators/hive_mind/install_generator.rb
218
220
  - lib/generators/hive_mind/start_generator.rb
219
221
  - lib/generators/hive_mind/templates/create_hive_mind_documents.rb
@@ -232,6 +234,8 @@ files:
232
234
  - lib/hokipoki/claude/parasite.rb
233
235
  - lib/hokipoki/claude/thought_interceptor.rb
234
236
  - lib/hokipoki/claude_auto_loader.rb
237
+ - lib/hokipoki/cli/gemini_connector.rb
238
+ - lib/hokipoki/cli/gemini_status_monitor.rb
235
239
  - lib/hokipoki/configuration.rb
236
240
  - lib/hokipoki/console.rb
237
241
  - lib/hokipoki/engine.rb
@@ -247,6 +251,7 @@ files:
247
251
  - lib/hokipoki/template_store.rb
248
252
  - lib/hokipoki/vector_engine.rb
249
253
  - lib/hokipoki/version.rb
254
+ - lib/tasks/gemini.rake
250
255
  homepage: https://github.com/rails-utilities/hokipoki
251
256
  licenses:
252
257
  - Proprietary