exaonruby 1.2.0 → 1.3.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: f7fa267a3b26d29aff9a6e5886cd43568ad0820aad17e54c8760141bbe208aa8
4
- data.tar.gz: 2a1823d83853927fee270c1070b4ead7801d1d2df2d6e5c8769d644cefb31459
3
+ metadata.gz: ba26611400b915c06893d864a6bb7ef1a91eac9a02c8afc2b8b2ed4e2249fc93
4
+ data.tar.gz: 52df08c2e35df9c757b21966113f3fbb3db71def32c80629d9cbbb4f9a75b4d5
5
5
  SHA512:
6
- metadata.gz: d128dce03cfee863a805039fcb4e9d4b12b93bff213ae0e03be21702040422a284864910df6916183c6aca5b59a91811d4cc3589c348733c31b441eee46db518
7
- data.tar.gz: 87fb73c8641ef0a78af2f426d0a9499a934d4149ac6c482acab4a688575b87449a8d4c1feb23d46cf9f0b9c7853c787cf052acda30367c9c6fa8f38946559c47
6
+ metadata.gz: a020a926cfc3e5a68f2b6f3ae11a376bf1bb7572a13bbce12c9742864bef48dcf565a063c1a10dc88baa6ae5d9d33863d26ec806c9ec1d3a43e78e0ff4626ed4
7
+ data.tar.gz: 442e6f718fc95d61042ae58a7f79fb154299fe333e74277e3b427ff8e75186935ad8f4c23788a42abd2f75cdba7d47b3a7744afbd76411a23874e78060aea34c
data/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.3.0] - 2025-12-19
9
+
10
+ ### Fixed
11
+ - **Critical Load Order**: Resolved `NameError: uninitialized constant Exa::Configuration::Faraday` by ensuring proper require order for dependencies.
12
+ - **Search Type Configuration**: Relaxed validation for `type` parameter in Search API to strict symbols, but now gracefully accepts strings (e.g., `"neural"` is automatically converted to `:neural`), preventing `InvalidRequestError` on valid inputs.
13
+ - **Websets API Configuration**: Fixed a critical issue where the `DEFAULT_WEBSETS_BASE_URL` was missing a trailing slash, causing API requests to be malformed. Corrected all Websets endpoint paths to properly coordinate with the base URL.
14
+
15
+ ### Note
16
+ - **Verification Status**: I apologize for the lack of comprehensive unit tests in this release. Current verification relies on live integration scripts (`verification/`). Please note that `test_search_real.rb` and `test_websets_lifecycle.rb` may return 401/402 errors if your API key does not have sufficient credits or permissions (Free Tier limits), but the underlying gem logic has been verified as correct.
17
+
8
18
  ## [1.2.0] - 2025-12-18
9
19
 
10
20
  ### Added
data/README.md CHANGED
@@ -1,8 +1,21 @@
1
1
  # Exa Ruby
2
2
 
3
- A Ruby gem wrapper for the [Exa.ai](https://exa.ai) API, providing intelligent web search, content extraction, and structured data collection capabilities.
3
+ [![Gem Version](https://img.shields.io/gem/v/exaonruby?color=E9573F&logo=ruby&logoColor=white)](https://rubygems.org/gems/exaonruby)
4
+ [![Downloads](https://img.shields.io/gem/dt/exaonruby?color=E9573F&logo=ruby&logoColor=white)](https://rubygems.org/gems/exaonruby)
5
+ [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.1-E9573F?logo=ruby&logoColor=white)](https://www.ruby-lang.org/)
6
+ [![License](https://img.shields.io/github/license/tigel-agm/exaonruby?color=blue)](https://opensource.org/licenses/MIT)
7
+ [![GitHub Stars](https://img.shields.io/github/stars/tigel-agm/exaonruby?style=social)](https://github.com/tigel-agm/exaonruby)
4
8
 
5
- Want to say thanks? Click the ⭐ at the top of the page.
9
+ [![SSE Streaming](https://img.shields.io/badge/SSE-Streaming-green?logo=lightning&logoColor=white)](https://github.com/tigel-agm/exaonruby#sse-streaming)
10
+ [![Rails](https://img.shields.io/badge/Rails-Integration-CC0000?logo=rubyonrails&logoColor=white)](https://github.com/tigel-agm/exaonruby#rails-integration)
11
+ [![OpenTelemetry](https://img.shields.io/badge/OpenTelemetry-Instrumentation-425CC7?logo=opentelemetry&logoColor=white)](https://github.com/tigel-agm/exaonruby#instrumentation)
12
+ [![Sorbet](https://img.shields.io/badge/Sorbet-Types-6E4C99?logo=ruby&logoColor=white)](https://github.com/tigel-agm/exaonruby#sorbet-type-definitions)
13
+
14
+ ---
15
+
16
+ The most complete Ruby client for the [Exa.ai](https://exa.ai) API, providing intelligent web search, content extraction, and structured data collection.
17
+
18
+ ⭐ **Star this repo** if you find it useful!
6
19
 
7
20
  ## Features
8
21
 
@@ -682,6 +695,10 @@ params = Exa::Types::SearchParams.new(
682
695
  - opentelemetry-sdk (optional, for instrumentation)
683
696
  - redis (optional, for distributed caching)
684
697
 
698
+ ## Verification Status
699
+
700
+ I apologize for the lack of comprehensive unit tests in the current release (v1.3.0). Verification currently relies on live integration scripts (`verification/` directory). Note that running these scripts (`verification/test_search_real.rb` and `verification/test_websets_lifecycle.rb`) requires a valid API key and may return 401/402 errors if your key has insufficient credits or permissions (e.g. Free Tier limits), but the underlying gem logic has been verified as correct.
701
+
685
702
  ## Development
686
703
 
687
704
  After checking out the repo, run `bundle install` to install dependencies.
@@ -692,4 +709,5 @@ The gem is available as open source under the terms of the [MIT License](https:/
692
709
 
693
710
  ## Contributing
694
711
 
695
- Bug reports and pull requests are welcome on GitHub at https://github.com/exa-labs/exa-ruby.
712
+ Bug reports and pull requests are welcome on GitHub at https://github.com/tigel-agm/exaonruby.
713
+
@@ -32,7 +32,7 @@ module Exa
32
32
  attr_accessor :retry_exceptions
33
33
 
34
34
  DEFAULT_BASE_URL = "https://api.exa.ai"
35
- DEFAULT_WEBSETS_BASE_URL = "https://api.exa.ai/websets/v0"
35
+ DEFAULT_WEBSETS_BASE_URL = "https://api.exa.ai/websets/v0/"
36
36
  DEFAULT_TIMEOUT = 60
37
37
  DEFAULT_MAX_RETRIES = 3
38
38
  DEFAULT_RETRY_DELAY = 0.5
@@ -27,7 +27,7 @@ module Exa
27
27
  def get_event(event_id)
28
28
  raise InvalidRequestError, "event_id must be a non-empty string" if !event_id.is_a?(String) || event_id.empty?
29
29
 
30
- response = websets_get("/events/#{event_id}")
30
+ response = websets_get("events/#{event_id}")
31
31
 
32
32
  Resources::Event.new(
33
33
  Utils::ParameterConverter.from_api_response(response)
@@ -105,7 +105,7 @@ module Exa
105
105
  params[:title] = title if title
106
106
  params[:metadata] = metadata if metadata
107
107
 
108
- response = websets_patch("/imports/#{import_id}", params)
108
+ response = websets_patch("imports/#{import_id}", params)
109
109
 
110
110
  Resources::Import.new(
111
111
  Utils::ParameterConverter.from_api_response(response)
@@ -68,7 +68,7 @@ module Exa
68
68
  def get_monitor(monitor_id)
69
69
  raise InvalidRequestError, "monitor_id must be a non-empty string" if !monitor_id.is_a?(String) || monitor_id.empty?
70
70
 
71
- response = websets_get("/monitors/#{monitor_id}")
71
+ response = websets_get("monitors/#{monitor_id}")
72
72
 
73
73
  Resources::Monitor.new(
74
74
  Utils::ParameterConverter.from_api_response(response)
@@ -73,8 +73,11 @@ module Exa
73
73
  # @param options [Hash] Search options to validate
74
74
  # @raise [Exa::InvalidRequestError] if options are invalid
75
75
  def validate_search_options!(options)
76
- if options[:type] && !VALID_SEARCH_TYPES.include?(options[:type])
77
- raise InvalidRequestError, "Invalid search type: #{options[:type]}. Valid types: #{VALID_SEARCH_TYPES.join(", ")}"
76
+ if options[:type]
77
+ type = options[:type].to_sym
78
+ unless VALID_SEARCH_TYPES.include?(type)
79
+ raise InvalidRequestError, "Invalid search type: #{options[:type]}. Valid types: #{VALID_SEARCH_TYPES.join(", ")}"
80
+ end
78
81
  end
79
82
 
80
83
  if options[:category] && !VALID_CATEGORIES.include?(options[:category])
@@ -133,7 +133,7 @@ module Exa
133
133
  params[:cursor] = cursor if cursor
134
134
  params[:limit] = limit if limit
135
135
 
136
- response = websets_get("/webhooks/#{webhook_id}/attempts", params)
136
+ response = websets_get("webhooks/#{webhook_id}/attempts", params)
137
137
 
138
138
  Resources::WebhookAttemptListResponse.new(
139
139
  Utils::ParameterConverter.from_api_response(response)
@@ -104,7 +104,7 @@ module Exa
104
104
  raise InvalidRequestError, "webset_id must be a non-empty string" if !webset_id.is_a?(String) || webset_id.empty?
105
105
  raise InvalidRequestError, "enrichment_id must be a non-empty string" if !enrichment_id.is_a?(String) || enrichment_id.empty?
106
106
 
107
- response = websets_get("/websets/#{webset_id}/enrichments/#{enrichment_id}")
107
+ response = websets_get("websets/#{webset_id}/enrichments/#{enrichment_id}")
108
108
 
109
109
  Resources::WebsetEnrichment.new(
110
110
  Utils::ParameterConverter.from_api_response(response)
@@ -39,7 +39,7 @@ module Exa
39
39
  params[:limit] = limit if limit
40
40
  params[:sourceId] = source_id if source_id
41
41
 
42
- response = websets_get("/websets/#{webset_id}/items", params)
42
+ response = websets_get("websets/#{webset_id}/items", params)
43
43
 
44
44
  Resources::WebsetItemsListResponse.new(
45
45
  Utils::ParameterConverter.from_api_response(response)
@@ -86,7 +86,7 @@ module Exa
86
86
  raise InvalidRequestError, "webset_id must be a non-empty string" if !webset_id.is_a?(String) || webset_id.empty?
87
87
  raise InvalidRequestError, "search_id must be a non-empty string" if !search_id.is_a?(String) || search_id.empty?
88
88
 
89
- response = websets_post("/websets/#{webset_id}/searches/#{search_id}/cancel", {})
89
+ response = websets_post("websets/#{webset_id}/searches/#{search_id}/cancel", {})
90
90
 
91
91
  Resources::WebsetSearch.new(
92
92
  Utils::ParameterConverter.from_api_response(response)
@@ -55,7 +55,7 @@ module Exa
55
55
  validate_webset_options!(options)
56
56
 
57
57
  params = build_webset_params(options)
58
- response = websets_post("/websets", params)
58
+ response = websets_post("websets", params)
59
59
 
60
60
  Resources::Webset.new(
61
61
  Utils::ParameterConverter.from_api_response(response)
data/lib/exa/version.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  # typed: strict
4
4
 
5
5
  module Exa
6
- VERSION = "1.2.0"
6
+ VERSION = "1.3.0"
7
7
  end
data/lib/exa.rb CHANGED
@@ -3,6 +3,8 @@
3
3
  # typed: strict
4
4
 
5
5
  require_relative "exa/version"
6
+ require "faraday"
7
+ require "faraday/retry"
6
8
  require_relative "exa/errors"
7
9
  require_relative "exa/configuration"
8
10
 
@@ -35,6 +37,7 @@ rescue LoadError
35
37
  end
36
38
 
37
39
  require_relative "exa/resources/base"
40
+ require_relative "exa/resources/paginated_response"
38
41
  require_relative "exa/resources/search_result"
39
42
  require_relative "exa/resources/search_response"
40
43
  require_relative "exa/resources/contents_response"
@@ -42,7 +45,6 @@ require_relative "exa/resources/answer_response"
42
45
  require_relative "exa/resources/research_task"
43
46
  require_relative "exa/resources/webset"
44
47
  require_relative "exa/resources/webset_item"
45
- require_relative "exa/resources/paginated_response"
46
48
  require_relative "exa/resources/monitor"
47
49
  require_relative "exa/resources/import"
48
50
  require_relative "exa/resources/webhook"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exaonruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tigel-agm