rails_ai 0.1.7 → 0.1.9

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: 79cd8a7525dc1139d6d697801f1e24f41d72157d97b1e42a049debce931146c1
4
- data.tar.gz: abf698a755293a28d98756a5979f69806ea91c5c3fbc25edab0d4ad349cdfb17
3
+ metadata.gz: 59f6834d30b4cf06108297201d34f4c51de26e46162d1a19290217d3e4219f17
4
+ data.tar.gz: e0b01802d3f3ce93e74fce16fdb307d063c77d0dff3a62c30992185adb8c27ce
5
5
  SHA512:
6
- metadata.gz: 28f77635e2609dc5aec01c34ee9a3a22e856ac3ef47733f913cc81c993426de7fc7f14e4a3ece60783387b98594122d611306f03ac1d38f085e7a4b1deaff610
7
- data.tar.gz: 5adcc56daa2903a3cd8969fe1d8be971a41e2beaf277f247b9feda2a25d6c194dd9719cfb1e1a8ac12e13ff06bc519d50494084052776895db0c6fbd69c914c4
6
+ metadata.gz: f04449c3223b6d793fb32cae60cbd78e122dd81a148cdd9452d53e8b2d3419ca5204c931cd937a25fbd5a5bbe5364b30654843e3aecc0be78de1eb2e1e082c99
7
+ data.tar.gz: e08d1b8bf4cf29a087c81d6a7b32f3e94778f31484fcb62d53e5fd99e91e8e7ae95f88b9d70c649ec786737a13d10860221c115c76ca2078656a93c21e82c905
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAi
4
- VERSION = "0.1.7"
4
+ VERSION = "0.1.9"
5
5
  end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'uri'
6
+
7
+ module RailsAi
8
+ module WebSearch
9
+ class SearchError < StandardError; end
10
+
11
+ class GoogleSearch
12
+ def initialize(api_key: nil, search_engine_id: nil)
13
+ @api_key = api_key || ENV['GOOGLE_SEARCH_API_KEY']
14
+ @search_engine_id = search_engine_id || ENV['GOOGLE_SEARCH_ENGINE_ID']
15
+ @base_url = 'https://www.googleapis.com/customsearch/v1'
16
+ end
17
+
18
+ def search(query, num_results: 5)
19
+ raise SearchError, "Google Search API key not configured" unless @api_key
20
+ raise SearchError, "Google Search Engine ID not configured" unless @search_engine_id
21
+
22
+ uri = URI(@base_url)
23
+ params = {
24
+ key: @api_key,
25
+ cx: @search_engine_id,
26
+ q: query,
27
+ num: num_results
28
+ }
29
+ uri.query = URI.encode_www_form(params)
30
+
31
+ response = Net::HTTP.get_response(uri)
32
+ raise SearchError, "Search failed: #{response.code}" unless response.code == '200'
33
+
34
+ data = JSON.parse(response.body)
35
+ format_results(data)
36
+ rescue => e
37
+ raise SearchError, "Web search error: #{e.message}"
38
+ end
39
+
40
+ private
41
+
42
+ def format_results(data)
43
+ results = data['items'] || []
44
+ results.map do |item|
45
+ {
46
+ title: item['title'],
47
+ link: item['link'],
48
+ snippet: item['snippet']
49
+ }
50
+ end
51
+ end
52
+ end
53
+
54
+ class DuckDuckGoSearch
55
+ def search(query, num_results: 5)
56
+ # Simple web scraping approach (for demo purposes)
57
+ # In production, you'd want to use a proper API
58
+ uri = URI("https://html.duckduckgo.com/html/?q=#{URI.encode_www_form_component(query)}")
59
+
60
+ response = Net::HTTP.get_response(uri)
61
+ raise SearchError, "Search failed: #{response.code}" unless response.code == '200'
62
+
63
+ # Parse HTML and extract results (simplified)
64
+ parse_duckduckgo_results(response.body, num_results)
65
+ rescue => e
66
+ raise SearchError, "Web search error: #{e.message}"
67
+ end
68
+
69
+ private
70
+
71
+ def parse_duckduckgo_results(html, num_results)
72
+ # This is a simplified parser - in production you'd use Nokogiri
73
+ results = []
74
+ lines = html.split("\n")
75
+
76
+ lines.each_with_index do |line, index|
77
+ if line.include?('class="result__title"') && results.length < num_results
78
+ title_line = lines[index + 1] rescue ""
79
+ snippet_line = lines[index + 3] rescue ""
80
+
81
+ results << {
82
+ title: title_line.strip,
83
+ link: "https://duckduckgo.com",
84
+ snippet: snippet_line.strip
85
+ }
86
+ end
87
+ end
88
+
89
+ results
90
+ end
91
+ end
92
+
93
+ class WebSearch
94
+ def initialize(provider: :google, **options)
95
+ @provider = case provider
96
+ when :google
97
+ GoogleSearch.new(**options)
98
+ when :duckduckgo
99
+ DuckDuckGoSearch.new(**options)
100
+ else
101
+ raise SearchError, "Unsupported search provider: #{provider}"
102
+ end
103
+ end
104
+
105
+ def search(query, **options)
106
+ @provider.search(query, **options)
107
+ end
108
+ end
109
+
110
+ # Convenience method
111
+ def self.search(query, provider: :google, **options)
112
+ WebSearch.new(provider: provider, **options).search(query)
113
+ end
114
+ end
115
+ end
data/lib/rails_ai.rb CHANGED
@@ -502,6 +502,8 @@ end
502
502
  end
503
503
  require_relative "rails_ai/web_search"
504
504
 
505
+ # Web-enhanced chat with real-time information
506
+
505
507
  # Web-enhanced chat with real-time information
506
508
  def self.chat_with_web_search(prompt, model: config.default_model, **opts)
507
509
  # Check if the prompt needs web search
@@ -532,3 +534,4 @@ require_relative "rails_ai/web_search"
532
534
  chat(prompt, model: model, **opts)
533
535
  end
534
536
  end
537
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_ai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Amah
@@ -339,6 +339,7 @@ files:
339
339
  - lib/rails_ai/security/secure_file_handler.rb
340
340
  - lib/rails_ai/security/secure_http_client.rb
341
341
  - lib/rails_ai/version.rb
342
+ - lib/rails_ai/web_search.rb
342
343
  - lib/rails_ai/window_context.rb
343
344
  - monitoring/ci_setup_guide.md
344
345
  - monitoring/enhanced_monitoring_script.rb