exa-ai 0.3.0 → 0.4.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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +94 -591
  3. data/exe/exa-ai +112 -9
  4. data/exe/exa-ai-answer +1 -5
  5. data/exe/exa-ai-context +1 -4
  6. data/exe/exa-ai-enrichment-cancel +107 -0
  7. data/exe/exa-ai-enrichment-create +235 -0
  8. data/exe/exa-ai-enrichment-delete +121 -0
  9. data/exe/exa-ai-enrichment-get +103 -0
  10. data/exe/exa-ai-enrichment-list +98 -0
  11. data/exe/exa-ai-enrichment-update +170 -0
  12. data/exe/exa-ai-find-similar +240 -0
  13. data/exe/exa-ai-get-contents +1 -4
  14. data/exe/exa-ai-research-get +1 -2
  15. data/exe/exa-ai-research-list +1 -2
  16. data/exe/exa-ai-research-start +1 -3
  17. data/exe/exa-ai-search +1 -3
  18. data/exe/exa-ai-webset-cancel +96 -0
  19. data/exe/exa-ai-webset-create +192 -0
  20. data/exe/exa-ai-webset-delete +110 -0
  21. data/exe/exa-ai-webset-get +92 -0
  22. data/exe/exa-ai-webset-item-delete +111 -0
  23. data/exe/exa-ai-webset-item-get +104 -0
  24. data/exe/exa-ai-webset-item-list +93 -0
  25. data/exe/exa-ai-webset-list +90 -0
  26. data/exe/exa-ai-webset-search-cancel +103 -0
  27. data/exe/exa-ai-webset-search-create +233 -0
  28. data/exe/exa-ai-webset-search-get +104 -0
  29. data/exe/exa-ai-webset-update +139 -0
  30. data/lib/exa/cli/base.rb +3 -3
  31. data/lib/exa/cli/formatters/enrichment_formatter.rb +69 -0
  32. data/lib/exa/cli/formatters/webset_formatter.rb +68 -0
  33. data/lib/exa/cli/formatters/webset_item_formatter.rb +69 -0
  34. data/lib/exa/client.rb +172 -0
  35. data/lib/exa/connection.rb +8 -1
  36. data/lib/exa/resources/webset.rb +74 -0
  37. data/lib/exa/resources/webset_collection.rb +33 -0
  38. data/lib/exa/resources/webset_enrichment.rb +71 -0
  39. data/lib/exa/resources/webset_enrichment_collection.rb +28 -0
  40. data/lib/exa/resources/webset_search.rb +112 -0
  41. data/lib/exa/services/parameter_converter.rb +1 -0
  42. data/lib/exa/services/websets/cancel.rb +36 -0
  43. data/lib/exa/services/websets/cancel_enrichment.rb +35 -0
  44. data/lib/exa/services/websets/cancel_search.rb +44 -0
  45. data/lib/exa/services/websets/create.rb +45 -0
  46. data/lib/exa/services/websets/create_enrichment.rb +35 -0
  47. data/lib/exa/services/websets/create_search.rb +48 -0
  48. data/lib/exa/services/websets/create_search_validator.rb +128 -0
  49. data/lib/exa/services/websets/create_validator.rb +189 -0
  50. data/lib/exa/services/websets/delete.rb +36 -0
  51. data/lib/exa/services/websets/delete_enrichment.rb +35 -0
  52. data/lib/exa/services/websets/delete_item.rb +20 -0
  53. data/lib/exa/services/websets/get_item.rb +20 -0
  54. data/lib/exa/services/websets/get_search.rb +43 -0
  55. data/lib/exa/services/websets/list.rb +25 -0
  56. data/lib/exa/services/websets/list_items.rb +20 -0
  57. data/lib/exa/services/websets/retrieve.rb +47 -0
  58. data/lib/exa/services/websets/retrieve_enrichment.rb +35 -0
  59. data/lib/exa/services/websets/update.rb +37 -0
  60. data/lib/exa/services/websets/update_enrichment.rb +36 -0
  61. data/lib/exa/services/websets_parameter_converter.rb +45 -0
  62. data/lib/exa/version.rb +1 -1
  63. data/lib/exa-ai.rb +5 -0
  64. data/lib/exa.rb +26 -0
  65. metadata +65 -3
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ # Validates parameters for webset creation
7
+ class CreateValidator
8
+ VALID_ENTITY_TYPES = %w[company person article research_paper custom].freeze
9
+ VALID_ENRICHMENT_FORMATS = %w[text date number options url].freeze
10
+ VALID_SOURCE_TYPES = %w[import webset].freeze
11
+
12
+ class << self
13
+ def validate!(params)
14
+ validate_has_search_or_import!(params)
15
+ validate_search!(params[:search]) if params[:search]
16
+ validate_import!(params[:import]) if params[:import]
17
+ validate_enrichments!(params[:enrichments]) if params[:enrichments]
18
+ validate_exclude!(params[:exclude]) if params[:exclude]
19
+ validate_external_id!(params[:externalId]) if params[:externalId]
20
+ validate_metadata!(params[:metadata]) if params[:metadata]
21
+ end
22
+
23
+ private
24
+
25
+ def validate_has_search_or_import!(params)
26
+ return if params[:search] || params[:import]
27
+
28
+ raise ArgumentError, "At least one of :search or :import is required"
29
+ end
30
+
31
+ def validate_search!(search)
32
+ raise ArgumentError, "search must be a Hash" unless search.is_a?(Hash)
33
+ raise ArgumentError, "search[:query] is required" unless search[:query]
34
+ raise ArgumentError, "search[:query] must be a String" unless search[:query].is_a?(String)
35
+ raise ArgumentError, "search[:query] cannot be empty" if search[:query].strip.empty?
36
+ raise ArgumentError, "search[:query] cannot exceed 5000 characters" if search[:query].length > 5000
37
+
38
+ validate_count!(search[:count]) if search[:count]
39
+ validate_entity!(search[:entity]) if search[:entity]
40
+ validate_criteria!(search[:criteria]) if search[:criteria]
41
+ validate_scope!(search[:scope]) if search[:scope]
42
+ validate_exclude_list!(search[:exclude]) if search[:exclude]
43
+ end
44
+
45
+ def validate_count!(count)
46
+ raise ArgumentError, "count must be a positive Integer" unless count.is_a?(Integer) && count > 0
47
+ end
48
+
49
+ def validate_entity!(entity)
50
+ raise ArgumentError, "entity must be a Hash" unless entity.is_a?(Hash)
51
+ raise ArgumentError, "entity[:type] is required" unless entity[:type]
52
+
53
+ type = entity[:type]
54
+ unless VALID_ENTITY_TYPES.include?(type)
55
+ raise ArgumentError, "entity[:type] must be one of: #{VALID_ENTITY_TYPES.join(', ')}"
56
+ end
57
+
58
+ if type == "custom"
59
+ raise ArgumentError, "entity[:description] is required for custom entity type" unless entity[:description]
60
+ validate_string_length!(entity[:description], "entity[:description]", min: 2, max: 200)
61
+ end
62
+ end
63
+
64
+ def validate_criteria!(criteria)
65
+ raise ArgumentError, "criteria must be an Array" unless criteria.is_a?(Array)
66
+ raise ArgumentError, "criteria must have at least 1 item" if criteria.empty?
67
+ raise ArgumentError, "criteria cannot have more than 5 items" if criteria.length > 5
68
+
69
+ criteria.each_with_index do |criterion, index|
70
+ raise ArgumentError, "criteria[#{index}] must be a Hash" unless criterion.is_a?(Hash)
71
+ raise ArgumentError, "criteria[#{index}][:description] is required" unless criterion[:description]
72
+ validate_string_length!(criterion[:description], "criteria[#{index}][:description]", min: 1, max: 1000)
73
+ end
74
+ end
75
+
76
+ def validate_scope!(scope)
77
+ raise ArgumentError, "scope must be an Array" unless scope.is_a?(Array)
78
+
79
+ scope.each_with_index do |item, index|
80
+ validate_source_reference!(item, "scope[#{index}]")
81
+
82
+ next unless item[:relationship]
83
+
84
+ rel = item[:relationship]
85
+ raise ArgumentError, "scope[#{index}][:relationship] must be a Hash" unless rel.is_a?(Hash)
86
+ raise ArgumentError, "scope[#{index}][:relationship][:definition] is required" unless rel[:definition]
87
+ raise ArgumentError, "scope[#{index}][:relationship][:limit] is required" unless rel[:limit]
88
+
89
+ limit = rel[:limit]
90
+ unless limit.is_a?(Integer) && limit >= 1 && limit <= 10
91
+ raise ArgumentError, "scope[#{index}][:relationship][:limit] must be an Integer between 1 and 10"
92
+ end
93
+ end
94
+ end
95
+
96
+ def validate_exclude_list!(exclude)
97
+ raise ArgumentError, "exclude must be an Array" unless exclude.is_a?(Array)
98
+
99
+ exclude.each_with_index do |item, index|
100
+ validate_source_reference!(item, "exclude[#{index}]")
101
+ end
102
+ end
103
+
104
+ def validate_import!(import)
105
+ raise ArgumentError, "import must be an Array" unless import.is_a?(Array)
106
+
107
+ import.each_with_index do |item, index|
108
+ validate_source_reference!(item, "import[#{index}]")
109
+ end
110
+ end
111
+
112
+ def validate_enrichments!(enrichments)
113
+ raise ArgumentError, "enrichments must be an Array" unless enrichments.is_a?(Array)
114
+
115
+ enrichments.each_with_index do |enrichment, index|
116
+ raise ArgumentError, "enrichments[#{index}] must be a Hash" unless enrichment.is_a?(Hash)
117
+ raise ArgumentError, "enrichments[#{index}][:description] is required" unless enrichment[:description]
118
+ validate_string_length!(enrichment[:description], "enrichments[#{index}][:description]", min: 1, max: 5000)
119
+
120
+ if enrichment[:format]
121
+ format = enrichment[:format]
122
+ unless VALID_ENRICHMENT_FORMATS.include?(format)
123
+ raise ArgumentError, "enrichments[#{index}][:format] must be one of: #{VALID_ENRICHMENT_FORMATS.join(', ')}"
124
+ end
125
+
126
+ if format == "options"
127
+ validate_enrichment_options!(enrichment[:options], index)
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ def validate_enrichment_options!(options, enrichment_index)
134
+ unless options.is_a?(Array)
135
+ raise ArgumentError, "enrichments[#{enrichment_index}][:options] is required when format is 'options'"
136
+ end
137
+
138
+ if options.empty? || options.length > 150
139
+ raise ArgumentError, "enrichments[#{enrichment_index}][:options] must have between 1 and 150 items"
140
+ end
141
+
142
+ options.each_with_index do |option, option_index|
143
+ unless option.is_a?(Hash) && option[:label]
144
+ raise ArgumentError, "enrichments[#{enrichment_index}][:options][#{option_index}][:label] is required"
145
+ end
146
+ end
147
+ end
148
+
149
+ def validate_exclude!(exclude)
150
+ validate_exclude_list!(exclude)
151
+ end
152
+
153
+ def validate_external_id!(external_id)
154
+ raise ArgumentError, "externalId must be a String" unless external_id.is_a?(String)
155
+ raise ArgumentError, "externalId cannot exceed 300 characters" if external_id.length > 300
156
+ end
157
+
158
+ def validate_metadata!(metadata)
159
+ raise ArgumentError, "metadata must be a Hash" unless metadata.is_a?(Hash)
160
+
161
+ metadata.each do |key, value|
162
+ raise ArgumentError, "metadata values must be Strings" unless value.is_a?(String)
163
+ raise ArgumentError, "metadata value for '#{key}' cannot exceed 1000 characters" if value.length > 1000
164
+ end
165
+ end
166
+
167
+ def validate_source_reference!(item, context)
168
+ raise ArgumentError, "#{context} must be a Hash" unless item.is_a?(Hash)
169
+ raise ArgumentError, "#{context}[:source] is required" unless item[:source]
170
+ raise ArgumentError, "#{context}[:id] is required" unless item[:id]
171
+
172
+ source = item[:source]
173
+ unless VALID_SOURCE_TYPES.include?(source)
174
+ raise ArgumentError, "#{context}[:source] must be one of: #{VALID_SOURCE_TYPES.join(', ')}"
175
+ end
176
+
177
+ raise ArgumentError, "#{context}[:id] must be a non-empty String" unless item[:id].is_a?(String) && !item[:id].empty?
178
+ end
179
+
180
+ def validate_string_length!(value, name, min: nil, max: nil)
181
+ raise ArgumentError, "#{name} must be a String" unless value.is_a?(String)
182
+ raise ArgumentError, "#{name} must be at least #{min} characters" if min && value.length < min
183
+ raise ArgumentError, "#{name} cannot exceed #{max} characters" if max && value.length > max
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class Delete
7
+ def initialize(connection, id:)
8
+ @connection = connection
9
+ @id = id
10
+ end
11
+
12
+ def call
13
+ response = @connection.delete("/websets/v0/websets/#{@id}")
14
+ body = response.body
15
+
16
+ Resources::Webset.new(
17
+ id: body["id"],
18
+ object: body["object"],
19
+ status: body["status"],
20
+ external_id: body["externalId"],
21
+ title: body["title"],
22
+ searches: body["searches"],
23
+ imports: body["imports"],
24
+ enrichments: body["enrichments"],
25
+ monitors: body["monitors"],
26
+ excludes: body["excludes"],
27
+ metadata: body["metadata"],
28
+ created_at: body["createdAt"],
29
+ updated_at: body["updatedAt"],
30
+ items: body["items"]
31
+ )
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class DeleteEnrichment
7
+ def initialize(connection, webset_id:, id:)
8
+ @connection = connection
9
+ @webset_id = webset_id
10
+ @id = id
11
+ end
12
+
13
+ def call
14
+ response = @connection.delete("/websets/v0/websets/#{@webset_id}/enrichments/#{@id}")
15
+ body = response.body
16
+
17
+ Resources::WebsetEnrichment.new(
18
+ id: body["id"],
19
+ object: body["object"],
20
+ status: body["status"],
21
+ webset_id: body["websetId"],
22
+ title: body["title"],
23
+ description: body["description"],
24
+ format: body["format"],
25
+ options: body["options"],
26
+ instructions: body["instructions"],
27
+ metadata: body["metadata"],
28
+ created_at: body["createdAt"],
29
+ updated_at: body["updatedAt"]
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class DeleteItem
7
+ def initialize(connection, webset_id:, id:)
8
+ @connection = connection
9
+ @webset_id = webset_id
10
+ @id = id
11
+ end
12
+
13
+ def call
14
+ @connection.delete("/websets/v0/websets/#{@webset_id}/items/#{@id}")
15
+ true
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class GetItem
7
+ def initialize(connection, webset_id:, id:)
8
+ @connection = connection
9
+ @webset_id = webset_id
10
+ @id = id
11
+ end
12
+
13
+ def call
14
+ response = @connection.get("/websets/v0/websets/#{@webset_id}/items/#{@id}")
15
+ response.body
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class GetSearch
7
+ def initialize(connection, webset_id:, id:)
8
+ @connection = connection
9
+ @webset_id = webset_id
10
+ @id = id
11
+ end
12
+
13
+ def call
14
+ response = @connection.get(
15
+ "/websets/v0/websets/#{@webset_id}/searches/#{@id}"
16
+ )
17
+ body = response.body
18
+
19
+ Resources::WebsetSearch.new(
20
+ id: body["id"],
21
+ object: body["object"],
22
+ status: body["status"],
23
+ webset_id: body["websetId"],
24
+ query: body["query"],
25
+ entity: body["entity"],
26
+ criteria: body["criteria"],
27
+ count: body["count"],
28
+ behavior: body["behavior"],
29
+ exclude: body["exclude"],
30
+ scope: body["scope"],
31
+ progress: body["progress"],
32
+ recall: body["recall"],
33
+ metadata: body["metadata"],
34
+ canceled_at: body["canceledAt"],
35
+ canceled_reason: body["canceledReason"],
36
+ created_at: body["createdAt"],
37
+ updated_at: body["updatedAt"]
38
+ )
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class List
7
+ def initialize(connection, **params)
8
+ @connection = connection
9
+ @params = params
10
+ end
11
+
12
+ def call
13
+ response = @connection.get("/websets/v0/websets", @params)
14
+ body = response.body
15
+
16
+ Resources::WebsetCollection.new(
17
+ data: body["data"],
18
+ has_more: body["hasMore"],
19
+ next_cursor: body["nextCursor"]
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class ListItems
7
+ def initialize(connection, webset_id:)
8
+ @connection = connection
9
+ @webset_id = webset_id
10
+ end
11
+
12
+ def call
13
+ response = @connection.get("/websets/v0/websets/#{@webset_id}/items")
14
+ body = response.body
15
+ body["data"] || []
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class Retrieve
7
+ def initialize(connection, id:, **params)
8
+ @connection = connection
9
+ @id = id
10
+ @params = normalize_params(params)
11
+ end
12
+
13
+ def call
14
+ response = @connection.get("/websets/v0/websets/#{@id}", @params)
15
+ body = response.body
16
+
17
+ Resources::Webset.new(
18
+ id: body["id"],
19
+ object: body["object"],
20
+ status: body["status"],
21
+ external_id: body["externalId"],
22
+ title: body["title"],
23
+ searches: body["searches"],
24
+ imports: body["imports"],
25
+ enrichments: body["enrichments"],
26
+ monitors: body["monitors"],
27
+ excludes: body["excludes"],
28
+ metadata: body["metadata"],
29
+ created_at: body["createdAt"],
30
+ updated_at: body["updatedAt"],
31
+ items: body["items"]
32
+ )
33
+ end
34
+
35
+ private
36
+
37
+ def normalize_params(params)
38
+ # Convert expand array to comma-separated string for API compatibility
39
+ if params[:expand].is_a?(Array)
40
+ params[:expand] = params[:expand].join(",")
41
+ end
42
+ params
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class RetrieveEnrichment
7
+ def initialize(connection, webset_id:, id:)
8
+ @connection = connection
9
+ @webset_id = webset_id
10
+ @id = id
11
+ end
12
+
13
+ def call
14
+ response = @connection.get("/websets/v0/websets/#{@webset_id}/enrichments/#{@id}")
15
+ body = response.body
16
+
17
+ Resources::WebsetEnrichment.new(
18
+ id: body["id"],
19
+ object: body["object"],
20
+ status: body["status"],
21
+ webset_id: body["websetId"],
22
+ title: body["title"],
23
+ description: body["description"],
24
+ format: body["format"],
25
+ options: body["options"],
26
+ instructions: body["instructions"],
27
+ metadata: body["metadata"],
28
+ created_at: body["createdAt"],
29
+ updated_at: body["updatedAt"]
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class Update
7
+ def initialize(connection, id:, **params)
8
+ @connection = connection
9
+ @id = id
10
+ @params = params
11
+ end
12
+
13
+ def call
14
+ response = @connection.post("/websets/v0/websets/#{@id}", @params)
15
+ body = response.body
16
+
17
+ Resources::Webset.new(
18
+ id: body["id"],
19
+ object: body["object"],
20
+ status: body["status"],
21
+ external_id: body["externalId"],
22
+ title: body["title"],
23
+ searches: body["searches"],
24
+ imports: body["imports"],
25
+ enrichments: body["enrichments"],
26
+ monitors: body["monitors"],
27
+ excludes: body["excludes"],
28
+ metadata: body["metadata"],
29
+ created_at: body["createdAt"],
30
+ updated_at: body["updatedAt"],
31
+ items: body["items"]
32
+ )
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ module Websets
6
+ class UpdateEnrichment
7
+ def initialize(connection, webset_id:, id:, **params)
8
+ @connection = connection
9
+ @webset_id = webset_id
10
+ @id = id
11
+ @params = params
12
+ end
13
+
14
+ def call
15
+ response = @connection.patch("/websets/v0/websets/#{@webset_id}/enrichments/#{@id}", @params)
16
+ body = response.body
17
+
18
+ Resources::WebsetEnrichment.new(
19
+ id: body["id"],
20
+ object: body["object"],
21
+ status: body["status"],
22
+ webset_id: body["websetId"],
23
+ title: body["title"],
24
+ description: body["description"],
25
+ format: body["format"],
26
+ options: body["options"],
27
+ instructions: body["instructions"],
28
+ metadata: body["metadata"],
29
+ created_at: body["createdAt"],
30
+ updated_at: body["updatedAt"]
31
+ )
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exa
4
+ module Services
5
+ # Converts Ruby parameter names (snake_case) to API format (camelCase) for Websets API
6
+ class WebsetsParameterConverter
7
+ def self.convert(params)
8
+ new.convert(params)
9
+ end
10
+
11
+ def convert(params)
12
+ converted = {}
13
+
14
+ params.each do |key, value|
15
+ converted_key = convert_key(key)
16
+ converted_value = convert_value(key, value)
17
+ converted[converted_key] = converted_value
18
+ end
19
+
20
+ converted
21
+ end
22
+
23
+ private
24
+
25
+ def convert_key(key)
26
+ case key
27
+ when :external_id then :externalId
28
+ else
29
+ key
30
+ end
31
+ end
32
+
33
+ def convert_value(key, value)
34
+ # Recursively convert nested hashes
35
+ if value.is_a?(Hash)
36
+ convert(value)
37
+ elsif value.is_a?(Array)
38
+ value.map { |item| item.is_a?(Hash) ? convert(item) : item }
39
+ else
40
+ value
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
data/lib/exa/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Exa
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
data/lib/exa-ai.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Main entry point for the exa-ai gem
4
+ # This file exists to avoid conflicts with the unrelated "exa" gem
5
+ require_relative "exa"
data/lib/exa.rb CHANGED
@@ -11,6 +11,11 @@ require_relative "exa/resources/research_task"
11
11
  require_relative "exa/resources/research_list"
12
12
  require_relative "exa/resources/answer"
13
13
  require_relative "exa/resources/context_result"
14
+ require_relative "exa/resources/webset_collection"
15
+ require_relative "exa/resources/webset"
16
+ require_relative "exa/resources/webset_search"
17
+ require_relative "exa/resources/webset_enrichment"
18
+ require_relative "exa/resources/webset_enrichment_collection"
14
19
  require_relative "exa/services/search"
15
20
  require_relative "exa/services/find_similar"
16
21
  require_relative "exa/services/get_contents"
@@ -20,6 +25,23 @@ require_relative "exa/services/research_list"
20
25
  require_relative "exa/services/answer"
21
26
  require_relative "exa/services/answer_stream"
22
27
  require_relative "exa/services/context"
28
+ require_relative "exa/services/websets/list"
29
+ require_relative "exa/services/websets/retrieve"
30
+ require_relative "exa/services/websets/delete"
31
+ require_relative "exa/services/websets/cancel"
32
+ require_relative "exa/services/websets/update"
33
+ require_relative "exa/services/websets/create"
34
+ require_relative "exa/services/websets/create_search"
35
+ require_relative "exa/services/websets/get_search"
36
+ require_relative "exa/services/websets/cancel_search"
37
+ require_relative "exa/services/websets/create_enrichment"
38
+ require_relative "exa/services/websets/retrieve_enrichment"
39
+ require_relative "exa/services/websets/update_enrichment"
40
+ require_relative "exa/services/websets/delete_enrichment"
41
+ require_relative "exa/services/websets/cancel_enrichment"
42
+ require_relative "exa/services/websets/get_item"
43
+ require_relative "exa/services/websets/delete_item"
44
+ require_relative "exa/services/websets/list_items"
23
45
  require_relative "exa/client"
24
46
  require_relative "exa/cli/base"
25
47
  require_relative "exa/cli/polling"
@@ -28,6 +50,10 @@ require_relative "exa/cli/formatters/search_formatter"
28
50
  require_relative "exa/cli/formatters/context_formatter"
29
51
  require_relative "exa/cli/formatters/contents_formatter"
30
52
  require_relative "exa/cli/formatters/research_formatter"
53
+ require_relative "exa/cli/formatters/answer_formatter"
54
+ require_relative "exa/cli/formatters/webset_formatter"
55
+ require_relative "exa/cli/formatters/webset_item_formatter"
56
+ require_relative "exa/cli/formatters/enrichment_formatter"
31
57
 
32
58
  module Exa
33
59
  # Module-level configuration