hokipoki 0.8.5 → 0.8.7

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: 1e6282c9c1b0a50ca6c78f7c19ef2268ab213738fb539ae497c10a9bb6ea14a1
4
- data.tar.gz: ade8ac41a2d503c2a46bfd68e418ff4b233e4d3cd00a31a19f2311c18e102c6b
3
+ metadata.gz: b5a7fa3a37f4a74900d6a2c6e901ac496e53bc5f393d6af9623e00d7fbdbf2d7
4
+ data.tar.gz: 0c8a79d2d72f2f096d7328b924e68d77c7d4181449f34db9544ded4c388a0fcb
5
5
  SHA512:
6
- metadata.gz: 81ed67ae4dcff72c7d43d169785bbc81320a6bc19c9cd89bb05a74ab95239bb0db521e46b92c7f0a39a4f88ce4f1ef4d4a845a7d76944c1f2b8bcaeae50da46a
7
- data.tar.gz: 9f66a3118b48c98f06e6242fc116f4d7e633c4ca2ac5f0e2cd5a672346873415f04ee2891d4bc1fb38c1ec90a2768d8c3704e48637095273ac9659fefe1c94a7
6
+ metadata.gz: af5e8f308a673ce3160b5ce0adb627edcebf8c04e7e6574f2cddd7ed70b2010829fdbecec8194865e87a612671aa8b58c406465d2a85711c97fa14e6fba265aa
7
+ data.tar.gz: 39ca391c5e1f001eef3d2dd5052402fe3493ed31c31c4ed8d4d146db9a85b0f0530c0d55a712fa68bcfcfc80a7ec52d40c956149231c337ece1e8bd874d356b4
data/bin/gemini_refiner CHANGED
@@ -15,7 +15,7 @@ class GeminiRefiner
15
15
  @status_file = '/tmp/gemini_status.log'
16
16
  @current_refinement_file = '/tmp/gemini_current_refinement.json'
17
17
  @batch_size = 10
18
- @sleep_interval = 5
18
+ @sleep_interval = 120 # 2 minutes
19
19
  @refinement_count = 0
20
20
  @start_time = Time.now
21
21
 
@@ -67,7 +67,7 @@ class GeminiRefiner
67
67
  puts "🎯 Configuration:"
68
68
  puts " Endpoint: #{@base_url}/api/gemini"
69
69
  puts " Batch Size: #{@batch_size} vectors"
70
- puts " Interval: #{@sleep_interval} seconds"
70
+ puts " Interval: #{@sleep_interval / 60} minutes"
71
71
  puts " Template: #{@template_file}"
72
72
  puts ""
73
73
  end
@@ -129,7 +129,7 @@ class GeminiRefiner
129
129
  display_current_stats
130
130
  end
131
131
  else
132
- puts "💤 No vectors to refine... waiting #{@sleep_interval}s"
132
+ puts "💤 No vectors to refine... waiting #{@sleep_interval / 60} minutes"
133
133
  clear_current_refinement
134
134
  end
135
135
 
@@ -138,7 +138,7 @@ class GeminiRefiner
138
138
  rescue => e
139
139
  log_status('error', "Refinement loop error: #{e.message}")
140
140
  puts "❌ Error in refinement loop: #{e.message}"
141
- puts " Retrying in #{@sleep_interval} seconds..."
141
+ puts " Retrying in #{@sleep_interval / 60} minutes..."
142
142
  sleep(@sleep_interval)
143
143
  end
144
144
  end
@@ -129,11 +129,31 @@ module HiveMind
129
129
  # Create smart retrieval engine
130
130
  template 'smart_retrieval_engine.rb', 'app/services/smart_retrieval_engine.rb'
131
131
  say @pastel.green("✓ Created app/services/smart_retrieval_engine.rb")
132
+
133
+ # Create Gemini API controller for vector refinement
134
+ directory 'api', 'app/controllers/api'
135
+ say @pastel.green("✓ Created app/controllers/api/gemini_controller.rb")
132
136
  end
133
137
 
134
138
  def setup_routing
135
- say "\n#{@pastel.cyan('🛣️ Skipping routes for lightweight install')}"
136
- say @pastel.green("✓ No additional routes needed")
139
+ say "\n#{@pastel.cyan('🛣️ Adding Gemini API routes')}"
140
+
141
+ # Add Gemini API routes
142
+ routes_content = <<~RUBY
143
+
144
+ # Gemini vector refinement API
145
+ namespace :api do
146
+ namespace :gemini do
147
+ get :health_check
148
+ get :unrefined_vectors
149
+ post :submit_refined
150
+ get :stats
151
+ end
152
+ end
153
+ RUBY
154
+
155
+ append_to_file 'config/routes.rb', routes_content
156
+ say @pastel.green("✓ Added Gemini API routes")
137
157
  end
138
158
 
139
159
  def create_cli_tools
@@ -0,0 +1,283 @@
1
+ class Api::GeminiController < ApplicationController
2
+ skip_before_action :verify_authenticity_token
3
+ before_action :log_gemini_activity, except: [:health_check]
4
+
5
+ # Health check endpoint
6
+ def health_check
7
+ render json: {
8
+ status: 'ok',
9
+ timestamp: Time.current,
10
+ system: 'hokipoki_gemini_api'
11
+ }
12
+ end
13
+
14
+ # Endpoint for Gemini to fetch unrefined vectors
15
+ def unrefined_vectors
16
+ begin
17
+ batch_size = params[:batch_size]&.to_i || 10
18
+ batch_size = [batch_size, 50].min # Cap at 50 for safety
19
+
20
+ vectors = HiveMindDocument.where(refined: false)
21
+ .limit(batch_size)
22
+ .order(:created_at)
23
+
24
+ response_data = {
25
+ vectors: vectors.map { |v| format_vector_for_gemini(v) },
26
+ refinement_template: refinement_template,
27
+ batch_info: {
28
+ requested: batch_size,
29
+ returned: vectors.count,
30
+ total_pending: HiveMindDocument.where(refined: false).count
31
+ },
32
+ timestamp: Time.current
33
+ }
34
+
35
+ log_gemini_status('info', "Served #{vectors.count} unrefined vectors to Gemini")
36
+
37
+ render json: response_data
38
+
39
+ rescue => e
40
+ log_gemini_status('error', "Failed to fetch unrefined vectors: #{e.message}")
41
+
42
+ render json: {
43
+ error: 'Failed to fetch vectors',
44
+ message: e.message,
45
+ timestamp: Time.current
46
+ }, status: 500
47
+ end
48
+ end
49
+
50
+ # Endpoint for Gemini to submit refined vectors
51
+ def submit_refined
52
+ begin
53
+ refined_data = JSON.parse(request.body.read)
54
+ processed_count = 0
55
+ errors = []
56
+
57
+ refined_data['vectors']&.each do |refined|
58
+ begin
59
+ vector = HiveMindDocument.find(refined['id'])
60
+
61
+ # Update with refined data
62
+ update_data = {
63
+ refined: true,
64
+ refined_at: Time.current,
65
+ refined_by: 'gemini'
66
+ }
67
+
68
+ # Add refined content if provided
69
+ if refined['chunks']
70
+ update_data[:chunks] = refined['chunks']
71
+ end
72
+
73
+ if refined['keywords']
74
+ update_data[:keywords] = refined['keywords']
75
+ end
76
+
77
+ if refined['generators']
78
+ update_data[:generators] = refined['generators']
79
+ end
80
+
81
+ # Store refined metadata
82
+ existing_metadata = vector.metadata || {}
83
+ update_data[:metadata] = existing_metadata.merge({
84
+ 'refined_by' => 'gemini',
85
+ 'refined_at' => Time.current.iso8601,
86
+ 'original_content_length' => vector.content&.length,
87
+ 'chunks_count' => refined['chunks']&.length,
88
+ 'keywords_count' => refined['keywords']&.length
89
+ })
90
+
91
+ vector.update!(update_data)
92
+ processed_count += 1
93
+
94
+ log_gemini_status('success', "Refined vector ##{vector.id} (#{refined['keywords']&.length || 0} keywords)")
95
+
96
+ rescue => e
97
+ error_msg = "Failed to update vector #{refined['id']}: #{e.message}"
98
+ errors << error_msg
99
+ log_gemini_status('error', error_msg)
100
+ end
101
+ end
102
+
103
+ response_data = {
104
+ status: 'success',
105
+ processed: processed_count,
106
+ errors: errors,
107
+ timestamp: Time.current
108
+ }
109
+
110
+ if errors.any?
111
+ response_data[:status] = 'partial_success'
112
+ render json: response_data, status: 207 # Multi-status
113
+ else
114
+ render json: response_data
115
+ end
116
+
117
+ rescue JSON::ParserError => e
118
+ log_gemini_status('error', "Invalid JSON in refined data: #{e.message}")
119
+
120
+ render json: {
121
+ error: 'Invalid JSON format',
122
+ message: e.message,
123
+ timestamp: Time.current
124
+ }, status: 400
125
+
126
+ rescue => e
127
+ log_gemini_status('error', "Failed to process refined vectors: #{e.message}")
128
+
129
+ render json: {
130
+ error: 'Failed to process refined vectors',
131
+ message: e.message,
132
+ timestamp: Time.current
133
+ }, status: 500
134
+ end
135
+ end
136
+
137
+ # Stats endpoint for monitoring
138
+ def stats
139
+ begin
140
+ stats = {
141
+ total_vectors: HiveMindDocument.count,
142
+ refined_vectors: HiveMindDocument.where(refined: true).count,
143
+ pending_vectors: HiveMindDocument.where(refined: false).count,
144
+ refinement_rate: calculate_refinement_rate,
145
+ last_activity: get_last_activity,
146
+ timestamp: Time.current
147
+ }
148
+
149
+ render json: stats
150
+
151
+ rescue => e
152
+ render json: {
153
+ error: 'Failed to generate stats',
154
+ message: e.message,
155
+ timestamp: Time.current
156
+ }, status: 500
157
+ end
158
+ end
159
+
160
+ private
161
+
162
+ def format_vector_for_gemini(vector)
163
+ {
164
+ id: vector.id,
165
+ content: vector.content,
166
+ source_type: vector.source_type,
167
+ source_id: vector.source_id,
168
+ metadata: vector.metadata || {},
169
+ created_at: vector.created_at,
170
+ content_length: vector.content&.length || 0,
171
+ preview: vector.content&.truncate(100)
172
+ }
173
+ end
174
+
175
+ def refinement_template
176
+ {
177
+ instruction: "Refine each vector into atomic facts with keywords and generators",
178
+ chunking_rules: {
179
+ max_words_per_chunk: 50,
180
+ min_words_per_chunk: 10,
181
+ overlap_words: 5,
182
+ preserve_context: true
183
+ },
184
+ keyword_extraction: {
185
+ keywords_per_chunk: "3-5",
186
+ types: ["technical", "contextual", "semantic"],
187
+ importance_threshold: 0.6
188
+ },
189
+ generator_creation: {
190
+ pattern: "trigger_keywords → response_template",
191
+ confidence_threshold: 0.7,
192
+ max_generators_per_chunk: 3
193
+ },
194
+ output_format: {
195
+ chunks: "Array of atomic fact strings",
196
+ keywords: "Array of keyword strings",
197
+ generators: "Array of {trigger: [...], template: '...', confidence: 0.0-1.0}"
198
+ },
199
+ example: {
200
+ input: "Rails authentication with Devise requires configuration",
201
+ expected_output: {
202
+ chunks: ["Rails authentication with Devise requires configuration"],
203
+ keywords: ["rails", "authentication", "devise", "configuration"],
204
+ generators: [
205
+ {
206
+ trigger: ["rails", "authentication", "devise"],
207
+ template: "For Rails authentication, use Devise gem with proper configuration",
208
+ confidence: 0.85
209
+ }
210
+ ]
211
+ }
212
+ }
213
+ }
214
+ end
215
+
216
+ def calculate_refinement_rate
217
+ # Calculate vectors refined in last hour
218
+ one_hour_ago = 1.hour.ago
219
+ recent_refined = HiveMindDocument.where(refined: true)
220
+ .where('refined_at > ?', one_hour_ago)
221
+ .count
222
+
223
+ # Return per minute rate
224
+ (recent_refined / 60.0).round(2)
225
+ end
226
+
227
+ def get_last_activity
228
+ begin
229
+ last_refined = HiveMindDocument.where(refined: true)
230
+ .order(:refined_at)
231
+ .last
232
+
233
+ if last_refined&.refined_at
234
+ {
235
+ type: 'refinement',
236
+ timestamp: last_refined.refined_at,
237
+ vector_id: last_refined.id
238
+ }
239
+ else
240
+ {
241
+ type: 'none',
242
+ timestamp: nil,
243
+ vector_id: nil
244
+ }
245
+ end
246
+ rescue
247
+ { type: 'error', timestamp: nil, vector_id: nil }
248
+ end
249
+ end
250
+
251
+ def log_gemini_activity
252
+ activity_log = "#{Time.current.strftime('%H:%M:%S')} - #{action_name} - #{request.remote_ip}"
253
+
254
+ # Log to Gemini status file
255
+ File.open('/tmp/gemini_status.log', 'a') do |f|
256
+ f.puts "#{Time.current.strftime('%H:%M:%S')} - api - #{activity_log}"
257
+ end
258
+ rescue
259
+ # Ignore logging errors
260
+ end
261
+
262
+ def log_gemini_status(level, message)
263
+ timestamp = Time.current.strftime('%H:%M:%S')
264
+ log_entry = "#{timestamp} - #{level} - #{message}"
265
+
266
+ # Log to Rails logger
267
+ case level
268
+ when 'error'
269
+ Rails.logger.error "[GEMINI] #{message}"
270
+ when 'success'
271
+ Rails.logger.info "[GEMINI] #{message}"
272
+ else
273
+ Rails.logger.debug "[GEMINI] #{message}"
274
+ end
275
+
276
+ # Log to Gemini status file for dashboard
277
+ File.open('/tmp/gemini_status.log', 'a') do |f|
278
+ f.puts log_entry
279
+ end
280
+ rescue
281
+ # Ignore logging errors
282
+ end
283
+ end
@@ -44,7 +44,7 @@ module Hokipoki
44
44
  endpoint: "http://localhost:3000/api/gemini/unrefined_vectors",
45
45
  submit_endpoint: "http://localhost:3000/api/gemini/submit_refined",
46
46
  batch_size: 10,
47
- interval: 5
47
+ interval: 120
48
48
  }
49
49
 
50
50
  File.write('/tmp/gemini_refinement_template.json', template.to_json)
@@ -1,3 +1,3 @@
1
1
  module Hokipoki
2
- VERSION = "0.8.5"
2
+ VERSION = "0.8.7"
3
3
  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.8.5
4
+ version: 0.8.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rails Utilities
@@ -232,6 +232,7 @@ files:
232
232
  - bin/gemini_refiner
233
233
  - lib/generators/hive_mind/install_generator.rb
234
234
  - lib/generators/hive_mind/start_generator.rb
235
+ - lib/generators/hive_mind/templates/api/gemini_controller.rb
235
236
  - lib/generators/hive_mind/templates/create_hive_mind_documents.rb
236
237
  - lib/generators/hive_mind/templates/embedding_service.rb
237
238
  - lib/generators/hive_mind/templates/hive_mind_document.rb