rails_ai 0.1.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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec_status +96 -0
  3. data/AGENT_GUIDE.md +513 -0
  4. data/Appraisals +49 -0
  5. data/COMMERCIAL_LICENSE_TEMPLATE.md +92 -0
  6. data/FEATURES.md +204 -0
  7. data/LEGAL_PROTECTION_GUIDE.md +222 -0
  8. data/LICENSE +62 -0
  9. data/LICENSE_SUMMARY.md +74 -0
  10. data/MIT-LICENSE +62 -0
  11. data/PERFORMANCE.md +300 -0
  12. data/PROVIDERS.md +495 -0
  13. data/README.md +454 -0
  14. data/Rakefile +11 -0
  15. data/SPEED_OPTIMIZATIONS.md +217 -0
  16. data/STRUCTURE.md +139 -0
  17. data/USAGE_GUIDE.md +288 -0
  18. data/app/channels/ai_stream_channel.rb +33 -0
  19. data/app/components/ai/prompt_component.rb +25 -0
  20. data/app/controllers/concerns/ai/context_aware.rb +77 -0
  21. data/app/controllers/concerns/ai/streaming.rb +41 -0
  22. data/app/helpers/ai_helper.rb +164 -0
  23. data/app/jobs/ai/generate_embedding_job.rb +25 -0
  24. data/app/jobs/ai/generate_summary_job.rb +25 -0
  25. data/app/models/concerns/ai/embeddable.rb +38 -0
  26. data/app/views/rails_ai/dashboard/index.html.erb +51 -0
  27. data/config/routes.rb +19 -0
  28. data/lib/generators/rails_ai/install/install_generator.rb +38 -0
  29. data/lib/rails_ai/agents/agent_manager.rb +258 -0
  30. data/lib/rails_ai/agents/agent_team.rb +243 -0
  31. data/lib/rails_ai/agents/base_agent.rb +331 -0
  32. data/lib/rails_ai/agents/collaboration.rb +238 -0
  33. data/lib/rails_ai/agents/memory.rb +116 -0
  34. data/lib/rails_ai/agents/message_bus.rb +95 -0
  35. data/lib/rails_ai/agents/specialized_agents.rb +391 -0
  36. data/lib/rails_ai/agents/task_queue.rb +111 -0
  37. data/lib/rails_ai/cache.rb +14 -0
  38. data/lib/rails_ai/config.rb +40 -0
  39. data/lib/rails_ai/context.rb +7 -0
  40. data/lib/rails_ai/context_analyzer.rb +86 -0
  41. data/lib/rails_ai/engine.rb +48 -0
  42. data/lib/rails_ai/events.rb +9 -0
  43. data/lib/rails_ai/image_context.rb +110 -0
  44. data/lib/rails_ai/performance.rb +231 -0
  45. data/lib/rails_ai/provider.rb +8 -0
  46. data/lib/rails_ai/providers/anthropic_adapter.rb +256 -0
  47. data/lib/rails_ai/providers/base.rb +60 -0
  48. data/lib/rails_ai/providers/dummy_adapter.rb +29 -0
  49. data/lib/rails_ai/providers/gemini_adapter.rb +509 -0
  50. data/lib/rails_ai/providers/openai_adapter.rb +535 -0
  51. data/lib/rails_ai/providers/secure_anthropic_adapter.rb +206 -0
  52. data/lib/rails_ai/providers/secure_openai_adapter.rb +284 -0
  53. data/lib/rails_ai/railtie.rb +48 -0
  54. data/lib/rails_ai/redactor.rb +12 -0
  55. data/lib/rails_ai/security/api_key_manager.rb +82 -0
  56. data/lib/rails_ai/security/audit_logger.rb +46 -0
  57. data/lib/rails_ai/security/error_handler.rb +62 -0
  58. data/lib/rails_ai/security/input_validator.rb +176 -0
  59. data/lib/rails_ai/security/secure_file_handler.rb +45 -0
  60. data/lib/rails_ai/security/secure_http_client.rb +177 -0
  61. data/lib/rails_ai/security.rb +0 -0
  62. data/lib/rails_ai/version.rb +5 -0
  63. data/lib/rails_ai/window_context.rb +103 -0
  64. data/lib/rails_ai.rb +502 -0
  65. data/monitoring/ci_setup_guide.md +214 -0
  66. data/monitoring/enhanced_monitoring_script.rb +237 -0
  67. data/monitoring/google_alerts_setup.md +42 -0
  68. data/monitoring_log_20250921.txt +0 -0
  69. data/monitoring_script.rb +161 -0
  70. data/rails_ai.gemspec +54 -0
  71. data/scripts/security_scanner.rb +353 -0
  72. data/setup_monitoring.sh +163 -0
  73. data/wiki/API-Documentation.md +734 -0
  74. data/wiki/Architecture-Overview.md +672 -0
  75. data/wiki/Contributing-Guide.md +407 -0
  76. data/wiki/Development-Setup.md +532 -0
  77. data/wiki/Home.md +278 -0
  78. data/wiki/Installation-Guide.md +527 -0
  79. data/wiki/Quick-Start.md +186 -0
  80. data/wiki/README.md +135 -0
  81. data/wiki/Release-Process.md +467 -0
  82. metadata +385 -0
data/lib/rails_ai.rb ADDED
@@ -0,0 +1,502 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails"
4
+ require "concurrent-ruby"
5
+ require "zlib"
6
+ require "digest"
7
+ require "net/http"
8
+ require "json"
9
+ require "base64"
10
+ require "securerandom"
11
+ require_relative "rails_ai/version"
12
+ require_relative "rails_ai/config"
13
+ require_relative "rails_ai/context"
14
+ require_relative "rails_ai/cache"
15
+ require_relative "rails_ai/redactor"
16
+ require_relative "rails_ai/events"
17
+ require_relative "rails_ai/provider"
18
+ require_relative "rails_ai/engine"
19
+ require_relative "rails_ai/railtie"
20
+ require_relative "rails_ai/providers/base"
21
+ require_relative "rails_ai/providers/secure_openai_adapter"
22
+ require_relative "rails_ai/providers/secure_anthropic_adapter"
23
+ require_relative "rails_ai/providers/gemini_adapter"
24
+ require_relative "rails_ai/providers/dummy_adapter"
25
+ require_relative "rails_ai/context_analyzer"
26
+ require_relative "rails_ai/window_context"
27
+ require_relative "rails_ai/image_context"
28
+ require_relative "rails_ai/performance"
29
+ require_relative "rails_ai/agents/base_agent"
30
+ require_relative "rails_ai/agents/memory"
31
+ require_relative "rails_ai/agents/agent_manager"
32
+ require_relative "rails_ai/agents/message_bus"
33
+ require_relative "rails_ai/agents/task_queue"
34
+ require_relative "rails_ai/agents/agent_team"
35
+ require_relative "rails_ai/agents/collaboration"
36
+ require_relative "rails_ai/agents/specialized_agents"
37
+ require_relative "rails_ai/security"
38
+
39
+ module RailsAi
40
+ # Performance optimizations
41
+ @connection_pool = nil
42
+ @batch_processor = nil
43
+ @smart_cache = nil
44
+ @request_deduplicator = nil
45
+ @performance_monitor = nil
46
+ @agent_manager = nil
47
+
48
+ class << self
49
+ # Version compatibility helpers
50
+ def rails_version
51
+ Rails.version.to_s
52
+ end
53
+
54
+ def rails_8?
55
+ Rails.version >= "8.0"
56
+ end
57
+
58
+ def rails_7?
59
+ Rails.version >= "7.0" && Rails.version < "8.0"
60
+ end
61
+
62
+ def rails_6?
63
+ Rails.version >= "6.0" && Rails.version < "7.0"
64
+ end
65
+
66
+ def rails_5?
67
+ Rails.version >= "5.2" && Rails.version < "6.0"
68
+ end
69
+
70
+ # Performance-optimized provider with lazy loading
71
+ def provider
72
+ @provider ||= Performance::LazyProvider.new do
73
+ case config.provider.to_sym
74
+ when :openai then Providers::SecureOpenAIAdapter.new
75
+ when :anthropic then Providers::SecureAnthropicAdapter.new
76
+ when :gemini then Providers::GeminiAdapter.new
77
+ when :dummy then Providers::DummyAdapter.new
78
+ else Providers::DummyAdapter.new
79
+ end
80
+ end
81
+ end
82
+
83
+ # Agent management
84
+ def agent_manager
85
+ @agent_manager ||= Agents::AgentManager.new
86
+ end
87
+
88
+ def create_agent(name:, role:, capabilities: [], **opts)
89
+ agent = Agents::BaseAgent.new(
90
+ name: name,
91
+ role: role,
92
+ capabilities: capabilities,
93
+ **opts
94
+ )
95
+ agent_manager.register_agent(agent)
96
+ agent
97
+ end
98
+
99
+ def create_research_agent(name: "ResearchAgent", **opts)
100
+ agent = Agents::ResearchAgent.new(name: name, **opts)
101
+ agent_manager.register_agent(agent)
102
+ agent
103
+ end
104
+
105
+ def create_creative_agent(name: "CreativeAgent", **opts)
106
+ agent = Agents::CreativeAgent.new(name: name, **opts)
107
+ agent_manager.register_agent(agent)
108
+ agent
109
+ end
110
+
111
+ def create_technical_agent(name: "TechnicalAgent", **opts)
112
+ agent = Agents::TechnicalAgent.new(name: name, **opts)
113
+ agent_manager.register_agent(agent)
114
+ agent
115
+ end
116
+
117
+ def create_coordinator_agent(name: "CoordinatorAgent", **opts)
118
+ agent = Agents::CoordinatorAgent.new(name: name, **opts)
119
+ agent_manager.register_agent(agent)
120
+ agent
121
+ end
122
+
123
+ def get_agent(name)
124
+ agent_manager.get_agent(name)
125
+ end
126
+
127
+ def list_agents
128
+ agent_manager.list_agents
129
+ end
130
+
131
+ def start_agents!
132
+ agent_manager.start!
133
+ end
134
+
135
+ def stop_agents!
136
+ agent_manager.stop!
137
+ end
138
+
139
+ # Task management
140
+ def submit_task(task)
141
+ agent_manager.submit_task(task)
142
+ end
143
+
144
+ def assign_task(task, agent_name)
145
+ agent_manager.assign_task_to_agent(task, agent_name)
146
+ end
147
+
148
+ def auto_assign_task(task)
149
+ agent_manager.auto_assign_task(task)
150
+ end
151
+
152
+ # Agent teams
153
+ def create_agent_team(name, agents, strategy: :round_robin)
154
+ agent_manager.create_agent_team(name, agents, strategy: strategy)
155
+ end
156
+
157
+ def orchestrate_collaboration(task, agent_names)
158
+ agent_manager.orchestrate_collaboration(task, agent_names)
159
+ end
160
+
161
+ # Agent communication
162
+ def send_agent_message(from_agent, to_agent, message)
163
+ agent_manager.send_message(from_agent, to_agent, message)
164
+ end
165
+
166
+ def broadcast_agent_message(from_agent, message, exclude: [])
167
+ agent_manager.broadcast_message(from_agent, message, exclude: exclude)
168
+ end
169
+
170
+ # Agent monitoring
171
+ def agent_system_status
172
+ agent_manager.system_status
173
+ end
174
+
175
+ def agent_health_check
176
+ agent_manager.health_check
177
+ end
178
+
179
+ # Performance monitoring
180
+ def performance_monitor
181
+ @performance_monitor ||= Performance::PerformanceMonitor.new
182
+ end
183
+
184
+ def metrics
185
+ performance_monitor.metrics
186
+ end
187
+
188
+ # Connection pool for HTTP requests
189
+ def connection_pool
190
+ @connection_pool ||= Performance::ConnectionPool.new(size: config.connection_pool_size)
191
+ end
192
+
193
+ # Smart caching with compression
194
+ def smart_cache
195
+ @smart_cache ||= Performance::SmartCache.new(
196
+ compression_threshold: config.compression_threshold
197
+ )
198
+ end
199
+
200
+ # Request deduplication
201
+ def request_deduplicator
202
+ @request_deduplicator ||= Performance::RequestDeduplicator.new
203
+ end
204
+
205
+ # Batch processor for multiple operations
206
+ def batch_processor
207
+ @batch_processor ||= Performance::BatchProcessor.new(
208
+ batch_size: config.batch_size,
209
+ flush_interval: config.flush_interval
210
+ )
211
+ end
212
+
213
+ # Optimized text-based AI operations with performance monitoring
214
+ def chat(prompt_or_messages, model: config.default_model, **opts)
215
+ performance_monitor.measure(:chat) do
216
+ messages = normalize_messages(prompt_or_messages)
217
+ cache_key = [:chat, model, messages.hash]
218
+
219
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
220
+ request_deduplicator.deduplicate(cache_key) do
221
+ provider.chat!(messages: messages, model: model, **opts)
222
+ end
223
+ end
224
+ end
225
+ end
226
+
227
+ def stream(prompt_or_messages, model: config.default_model, **opts, &block)
228
+ performance_monitor.measure(:stream) do
229
+ messages = normalize_messages(prompt_or_messages)
230
+
231
+ # Use connection pool for streaming
232
+ connection_pool.with_connection do |connection|
233
+ provider.stream_chat!(messages: messages, model: model, **opts, &block)
234
+ end
235
+ end
236
+ end
237
+
238
+ def embed(texts, model: config.default_model, **opts)
239
+ performance_monitor.measure(:embed) do
240
+ texts = Array(texts)
241
+ cache_key = [:embed, model, texts.hash]
242
+
243
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
244
+ request_deduplicator.deduplicate(cache_key) do
245
+ provider.embed!(texts: texts, model: model, **opts)
246
+ end
247
+ end
248
+ end
249
+ end
250
+
251
+ # Optimized image operations
252
+ def generate_image(prompt, model: "dall-e-3", size: "1024x1024", quality: "standard", **opts)
253
+ performance_monitor.measure(:generate_image) do
254
+ cache_key = [:image, model, prompt.hash, size, quality]
255
+
256
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
257
+ request_deduplicator.deduplicate(cache_key) do
258
+ provider.generate_image!(prompt: prompt, model: model, size: size, quality: quality, **opts)
259
+ end
260
+ end
261
+ end
262
+ end
263
+
264
+ def edit_image(image, prompt, mask: nil, size: "1024x1024", **opts)
265
+ performance_monitor.measure(:edit_image) do
266
+ cache_key = [:image_edit, prompt.hash, image.hash, size]
267
+
268
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
269
+ request_deduplicator.deduplicate(cache_key) do
270
+ provider.edit_image!(image: image, prompt: prompt, mask: mask, size: size, **opts)
271
+ end
272
+ end
273
+ end
274
+ end
275
+
276
+ def create_variation(image, size: "1024x1024", **opts)
277
+ performance_monitor.measure(:create_variation) do
278
+ cache_key = [:image_variation, image.hash, size]
279
+
280
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
281
+ request_deduplicator.deduplicate(cache_key) do
282
+ provider.create_variation!(image: image, size: size, **opts)
283
+ end
284
+ end
285
+ end
286
+ end
287
+
288
+ # Optimized video operations
289
+ def generate_video(prompt, model: "sora", duration: 5, **opts)
290
+ performance_monitor.measure(:generate_video) do
291
+ cache_key = [:video, model, prompt.hash, duration]
292
+
293
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
294
+ request_deduplicator.deduplicate(cache_key) do
295
+ provider.generate_video!(prompt: prompt, model: model, duration: duration, **opts)
296
+ end
297
+ end
298
+ end
299
+ end
300
+
301
+ def edit_video(video, prompt, **opts)
302
+ performance_monitor.measure(:edit_video) do
303
+ cache_key = [:video_edit, prompt.hash, video.hash]
304
+
305
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
306
+ request_deduplicator.deduplicate(cache_key) do
307
+ provider.edit_video!(video: video, prompt: prompt, **opts)
308
+ end
309
+ end
310
+ end
311
+ end
312
+
313
+ # Optimized audio operations
314
+ def generate_speech(text, model: "tts-1", voice: "alloy", **opts)
315
+ performance_monitor.measure(:generate_speech) do
316
+ cache_key = [:speech, model, text.hash, voice]
317
+
318
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
319
+ request_deduplicator.deduplicate(cache_key) do
320
+ provider.generate_speech!(text: text, model: model, voice: voice, **opts)
321
+ end
322
+ end
323
+ end
324
+ end
325
+
326
+ def transcribe_audio(audio, model: "whisper-1", **opts)
327
+ performance_monitor.measure(:transcribe_audio) do
328
+ cache_key = [:transcription, model, audio.hash]
329
+
330
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
331
+ request_deduplicator.deduplicate(cache_key) do
332
+ provider.transcribe_audio!(audio: audio, model: model, **opts)
333
+ end
334
+ end
335
+ end
336
+ end
337
+
338
+ # Optimized multimodal analysis
339
+ def analyze_image(image, prompt, model: "gpt-4o", **opts)
340
+ performance_monitor.measure(:analyze_image) do
341
+ cache_key = [:image_analysis, model, prompt.hash, image.hash]
342
+
343
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
344
+ request_deduplicator.deduplicate(cache_key) do
345
+ provider.analyze_image!(image: image, prompt: prompt, model: model, **opts)
346
+ end
347
+ end
348
+ end
349
+ end
350
+
351
+ def analyze_video(video, prompt, model: "gpt-4o", **opts)
352
+ performance_monitor.measure(:analyze_video) do
353
+ cache_key = [:video_analysis, model, prompt.hash, video.hash]
354
+
355
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
356
+ request_deduplicator.deduplicate(cache_key) do
357
+ provider.analyze_video!(video: video, prompt: prompt, model: model, **opts)
358
+ end
359
+ end
360
+ end
361
+ end
362
+
363
+ # Batch operations for multiple requests
364
+ def batch_chat(requests)
365
+ performance_monitor.measure(:batch_chat) do
366
+ requests.map do |request|
367
+ batch_processor.add_operation(-> { chat(request[:prompt], **request.except(:prompt)) })
368
+ end
369
+ end
370
+ end
371
+
372
+ def batch_embed(texts_array)
373
+ performance_monitor.measure(:batch_embed) do
374
+ texts_array.map do |texts|
375
+ batch_processor.add_operation(-> { embed(texts) })
376
+ end
377
+ end
378
+ end
379
+
380
+ # Context-aware AI operations (optimized)
381
+ def analyze_image_with_context(image, prompt, user_context: {}, window_context: {}, image_context: {}, **opts)
382
+ performance_monitor.measure(:analyze_image_with_context) do
383
+ cache_key = [:context_image_analysis, prompt.hash, image.hash, user_context.hash, window_context.hash, image_context.hash]
384
+
385
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
386
+ analyzer = ContextAnalyzer.new(
387
+ user_context: user_context,
388
+ window_context: window_context,
389
+ image_context: image_context
390
+ )
391
+ analyzer.analyze_with_context(image, prompt, **opts)
392
+ end
393
+ end
394
+ end
395
+
396
+ def generate_with_context(prompt, user_context: {}, window_context: {}, **opts)
397
+ performance_monitor.measure(:generate_with_context) do
398
+ cache_key = [:context_generate, prompt.hash, user_context.hash, window_context.hash]
399
+
400
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
401
+ analyzer = ContextAnalyzer.new(
402
+ user_context: user_context,
403
+ window_context: window_context
404
+ )
405
+ analyzer.generate_with_context(prompt, **opts)
406
+ end
407
+ end
408
+ end
409
+
410
+ def generate_image_with_context(prompt, user_context: {}, window_context: {}, **opts)
411
+ performance_monitor.measure(:generate_image_with_context) do
412
+ cache_key = [:context_image_generate, prompt.hash, user_context.hash, window_context.hash]
413
+
414
+ smart_cache.fetch(cache_key, expires_in: config.cache_ttl) do
415
+ analyzer = ContextAnalyzer.new(
416
+ user_context: user_context,
417
+ window_context: window_context
418
+ )
419
+ analyzer.generate_image_with_context(prompt, **opts)
420
+ end
421
+ end
422
+ end
423
+
424
+ # Convenience methods for common AI tasks (optimized)
425
+ def summarize(content, **opts)
426
+ chat("Summarize the following content: #{content}", **opts)
427
+ end
428
+
429
+ def translate(content, target_language, **opts)
430
+ chat("Translate the following content to #{target_language}: #{content}", **opts)
431
+ end
432
+
433
+ def classify(content, categories, **opts)
434
+ chat("Classify the following content into one of these categories: #{categories.join(", ")}. Content: #{content}", **opts)
435
+ end
436
+
437
+ def extract_entities(content, **opts)
438
+ chat("Extract named entities from the following content: #{content}", **opts)
439
+ end
440
+
441
+ def generate_code(prompt, language: "ruby", **opts)
442
+ chat("Generate #{language} code for: #{prompt}", **opts)
443
+ end
444
+
445
+ def explain_code(code, language: "ruby", **opts)
446
+ chat("Explain this #{language} code: #{code}", **opts)
447
+ end
448
+
449
+ # Performance utilities
450
+ def warmup!
451
+ # Pre-initialize components for faster first requests
452
+ provider
453
+ connection_pool
454
+ smart_cache
455
+ request_deduplicator
456
+ batch_processor
457
+ agent_manager
458
+ end
459
+
460
+ def clear_cache!
461
+ Rails.cache.delete_matched("rails_ai:*") if defined?(Rails) && Rails.cache
462
+ end
463
+
464
+ def reset_performance_metrics!
465
+ @performance_monitor = Performance::PerformanceMonitor.new
466
+ end
467
+
468
+ private
469
+
470
+ def normalize_messages(prompt_or_messages)
471
+ messages = prompt_or_messages.is_a?(Array) ? prompt_or_messages : [{role: "user", content: prompt_or_messages}]
472
+ text = RailsAi::Redactor.call(messages.last[:content])
473
+ messages[-1] = messages.last.merge(content: text)
474
+ messages
475
+ end
476
+ end
477
+ end
478
+
479
+ # Security methods
480
+ def self.validate_input(input, type: :text)
481
+ Security::InputValidator.send("validate_#{type}_input", input)
482
+ end
483
+
484
+ def self.sanitize_content(content)
485
+ Security::ContentSanitizer.sanitize_content(content)
486
+ end
487
+
488
+ def self.secure_api_key(env_var, required: true)
489
+ Security::APIKeyManager.secure_fetch(env_var, required: required)
490
+ end
491
+
492
+ def self.mask_api_key(key)
493
+ Security::APIKeyManager.mask_key(key)
494
+ end
495
+
496
+ def self.log_security_event(event_type, details = {})
497
+ Security::AuditLogger.log_security_event(event_type, details)
498
+ end
499
+
500
+ def self.handle_security_error(error, context = {})
501
+ Security::ErrorHandler.handle_security_error(error, context)
502
+ end
@@ -0,0 +1,214 @@
1
+ # CI Monitoring Setup Guide
2
+
3
+ ## 🚀 Continuous Monitoring via GitHub Actions
4
+
5
+ Your Rails AI gem now has automated monitoring that runs continuously!
6
+
7
+ ## 📋 What's Set Up
8
+
9
+ ### 1. Daily Monitoring Workflow (`.github/workflows/monitoring.yml`)
10
+ - **Runs**: Every day at 9 AM UTC
11
+ - **Manual**: Can be triggered manually
12
+ - **Triggers**: On pushes to main branch
13
+ - **Checks**: RubyGems, GitHub, Google searches
14
+ - **Outputs**: Monitoring reports and logs
15
+
16
+ ### 2. Security Monitoring Workflow (`.github/workflows/security-monitoring.yml`)
17
+ - **Runs**: Every 6 hours
18
+ - **Focus**: Security and plagiarism detection
19
+ - **Checks**: Code similarity, package conflicts
20
+ - **Outputs**: Security reports
21
+
22
+ ## 🔧 Setup Steps
23
+
24
+ ### Step 1: Enable GitHub Actions
25
+ 1. Go to your GitHub repository
26
+ 2. Click "Actions" tab
27
+ 3. Enable GitHub Actions if not already enabled
28
+
29
+ ### Step 2: Add API Keys (Optional but Recommended)
30
+ 1. Go to repository Settings → Secrets and variables → Actions
31
+ 2. Add these secrets:
32
+ - `GOOGLE_API_KEY`: For Google search monitoring
33
+ - `GITHUB_PAT`: For GitHub API access
34
+ - `RUBYGEMS_API_KEY`: For RubyGems API access
35
+
36
+ ### Step 3: Test the Workflows
37
+ 1. Go to Actions tab
38
+ 2. Click "Rails AI Monitoring"
39
+ 3. Click "Run workflow" to test manually
40
+
41
+ ## �� Monitoring Outputs
42
+
43
+ ### Daily Reports
44
+ - **Location**: Actions → Artifacts
45
+ - **Files**: `monitoring-results-{run_number}`
46
+ - **Content**: Detailed monitoring logs
47
+
48
+ ### Security Reports
49
+ - **Location**: Actions → Artifacts
50
+ - **Files**: `security-report-{run_number}`
51
+ - **Content**: Security and plagiarism checks
52
+
53
+ ## 🔔 Notifications
54
+
55
+ ### Email Notifications
56
+ - GitHub will email you when workflows fail
57
+ - Set up email notifications in GitHub settings
58
+
59
+ ### Slack/Discord Integration (Optional)
60
+ Add this to your workflow for Slack notifications:
61
+
62
+ ```yaml
63
+ - name: Notify Slack
64
+ if: failure()
65
+ uses: 8398a7/action-slack@v3
66
+ with:
67
+ status: failure
68
+ text: "Rails AI monitoring found potential issues!"
69
+ env:
70
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
71
+ ```
72
+
73
+ ## 📈 Monitoring Schedule
74
+
75
+ ### Daily (9 AM UTC)
76
+ - RubyGems package monitoring
77
+ - GitHub repository searches
78
+ - Google search monitoring
79
+ - Generate monitoring report
80
+
81
+ ### Every 6 Hours
82
+ - Security checks
83
+ - Code plagiarism detection
84
+ - Package conflict detection
85
+ - Generate security report
86
+
87
+ ## 🛠️ Customization
88
+
89
+ ### Change Schedule
90
+ Edit the cron expressions in the workflow files:
91
+ ```yaml
92
+ schedule:
93
+ - cron: '0 9 * * *' # Daily at 9 AM UTC
94
+ - cron: '0 */6 * * *' # Every 6 hours
95
+ ```
96
+
97
+ ### Add More Checks
98
+ Add new monitoring steps to the workflow:
99
+ ```yaml
100
+ - name: Check specific website
101
+ run: |
102
+ curl -s "https://example.com/search?q=rails_ai" | grep -i "commercial"
103
+ ```
104
+
105
+ ### Add More APIs
106
+ Add API keys to repository secrets and use them:
107
+ ```yaml
108
+ env:
109
+ CUSTOM_API_KEY: ${{ secrets.CUSTOM_API_KEY }}
110
+ ```
111
+
112
+ ## 📱 Mobile Monitoring
113
+
114
+ ### GitHub Mobile App
115
+ - Get notifications on your phone
116
+ - View monitoring results anywhere
117
+ - Respond to alerts immediately
118
+
119
+ ### Email Alerts
120
+ - Set up email notifications for failures
121
+ - Get daily monitoring summaries
122
+ - Receive security alerts
123
+
124
+ ## 🔍 What Gets Monitored
125
+
126
+ ### RubyGems
127
+ - New packages with similar names
128
+ - Commercial usage in descriptions
129
+ - Download statistics
130
+ - Package dependencies
131
+
132
+ ### GitHub
133
+ - Repositories using your gem
134
+ - Forks of your code
135
+ - Similar project names
136
+ - Commercial usage indicators
137
+
138
+ ### Google Search
139
+ - Web mentions of your gem
140
+ - Commercial usage discussions
141
+ - Competitor analysis
142
+ - Brand monitoring
143
+
144
+ ## 🚨 Alert Conditions
145
+
146
+ ### High Priority
147
+ - Direct code copying
148
+ - Commercial use without license
149
+ - Trademark infringement
150
+ - Patent violations
151
+
152
+ ### Medium Priority
153
+ - Similar package names
154
+ - Competitive analysis
155
+ - Usage discussions
156
+ - Feature requests
157
+
158
+ ### Low Priority
159
+ - General mentions
160
+ - Educational usage
161
+ - Open source contributions
162
+ - Community discussions
163
+
164
+ ## 📊 Monitoring Dashboard
165
+
166
+ ### GitHub Actions Tab
167
+ - View all monitoring runs
168
+ - See success/failure status
169
+ - Download monitoring reports
170
+ - View detailed logs
171
+
172
+ ### Artifacts
173
+ - Download monitoring results
174
+ - View security reports
175
+ - Analyze trends over time
176
+ - Share reports with legal team
177
+
178
+ ## 🔧 Troubleshooting
179
+
180
+ ### Common Issues
181
+ 1. **Workflow not running**: Check if GitHub Actions is enabled
182
+ 2. **API errors**: Verify API keys are set correctly
183
+ 3. **Permission errors**: Check repository permissions
184
+ 4. **Rate limiting**: Add delays between API calls
185
+
186
+ ### Debug Mode
187
+ Add this to see detailed logs:
188
+ ```yaml
189
+ - name: Debug monitoring
190
+ run: |
191
+ echo "Debug information:"
192
+ echo "Date: $(date)"
193
+ echo "Ruby version: $(ruby --version)"
194
+ echo "Working directory: $(pwd)"
195
+ ```
196
+
197
+ ## 📞 Support
198
+
199
+ ### GitHub Actions Documentation
200
+ - https://docs.github.com/en/actions
201
+
202
+ ### Monitoring Script Issues
203
+ - Check the monitoring_script.rb file
204
+ - Review the monitoring logs
205
+ - Test locally first
206
+
207
+ ### Legal Questions
208
+ - Contact your IP lawyer
209
+ - Review the legal protection guide
210
+ - Use the cease and desist template
211
+
212
+ ---
213
+
214
+ **Your Rails AI gem is now continuously monitored! 🛡️**