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,93 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Parse arguments
7
+ webset_id = nil
8
+ api_key = nil
9
+ output_format = "json"
10
+
11
+ args = ARGV.dup
12
+ while args.any?
13
+ arg = args.shift
14
+ case arg
15
+ when "--api-key"
16
+ api_key = args.shift
17
+ when "--output-format"
18
+ output_format = args.shift
19
+ when "--help", "-h"
20
+ puts <<~HELP
21
+ Usage: exa-ai webset-item-list <webset_id> [OPTIONS]
22
+
23
+ List all items in a webset
24
+
25
+ Arguments:
26
+ webset_id ID of the webset (required)
27
+
28
+ Options:
29
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
30
+ --output-format FMT Output format: json, pretty, or text (default: json)
31
+ --help, -h Show this help message
32
+
33
+ Examples:
34
+ exa-ai webset-item-list ws_123
35
+ exa-ai webset-item-list ws_123 --output-format pretty
36
+ exa-ai webset-item-list ws_123 --output-format text
37
+ HELP
38
+ exit 0
39
+ else
40
+ # First positional argument is webset_id
41
+ if webset_id.nil?
42
+ webset_id = arg
43
+ else
44
+ $stderr.puts "Unknown option: #{arg}"
45
+ exit 1
46
+ end
47
+ end
48
+ end
49
+
50
+ # Validate
51
+ if webset_id.nil?
52
+ $stderr.puts "Error: webset_id argument is required"
53
+ $stderr.puts "Usage: exa-ai webset-item-list <webset_id> [OPTIONS]"
54
+ $stderr.puts "Try 'exa-ai webset-item-list --help' for more information"
55
+ exit 1
56
+ end
57
+
58
+ begin
59
+ # Resolve API key and format
60
+ api_key = Exa::CLI::Base.resolve_api_key(api_key)
61
+ output_format = Exa::CLI::Base.resolve_output_format(output_format)
62
+
63
+ # Build client
64
+ client = Exa::CLI::Base.build_client(api_key)
65
+
66
+ # List items
67
+ items = client.list_items(webset_id: webset_id)
68
+
69
+ # Format and output
70
+ output = Exa::CLI::Formatters::WebsetItemFormatter.format_collection(items, output_format)
71
+ puts output
72
+
73
+ rescue Exa::NotFound => e
74
+ $stderr.puts "Webset not found: #{e.message}"
75
+ exit 1
76
+ rescue Exa::Unauthorized => e
77
+ $stderr.puts "Authentication error: #{e.message}"
78
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
79
+ exit 1
80
+ rescue Exa::ClientError => e
81
+ $stderr.puts "Client error: #{e.message}"
82
+ exit 1
83
+ rescue Exa::ServerError => e
84
+ $stderr.puts "Server error: #{e.message}"
85
+ exit 1
86
+ rescue Exa::Error => e
87
+ $stderr.puts "Error: #{e.message}"
88
+ exit 1
89
+ rescue StandardError => e
90
+ $stderr.puts "Unexpected error: #{e.message}"
91
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
92
+ exit 1
93
+ end
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Parse arguments
7
+ limit = nil
8
+ cursor = nil
9
+ api_key = nil
10
+ output_format = "json"
11
+
12
+ args = ARGV.dup
13
+ while args.any?
14
+ arg = args.shift
15
+ case arg
16
+ when "--limit"
17
+ limit = args.shift&.to_i
18
+ when "--cursor"
19
+ cursor = args.shift
20
+ when "--api-key"
21
+ api_key = args.shift
22
+ when "--output-format"
23
+ output_format = args.shift
24
+ when "--help", "-h"
25
+ puts <<~HELP
26
+ Usage: exa-ai webset-list [OPTIONS]
27
+
28
+ List all websets with optional pagination
29
+
30
+ Options:
31
+ --limit N Maximum number of websets to return (default: 25, max: 100)
32
+ --cursor CURSOR Cursor for pagination (use nextCursor from previous response)
33
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
34
+ --output-format FMT Output format: json, pretty, or text (default: json)
35
+ --help, -h Show this help message
36
+
37
+ Examples:
38
+ exa-ai webset-list
39
+ exa-ai webset-list --limit 10
40
+ exa-ai webset-list --limit 5 --cursor "abc123"
41
+ exa-ai webset-list --output-format pretty
42
+ HELP
43
+ exit 0
44
+ else
45
+ $stderr.puts "Unknown option: #{arg}"
46
+ exit 1
47
+ end
48
+ end
49
+
50
+ begin
51
+ # Resolve API key and format
52
+ api_key = Exa::CLI::Base.resolve_api_key(api_key)
53
+ output_format = Exa::CLI::Base.resolve_output_format(output_format)
54
+
55
+ # Build client
56
+ client = Exa::CLI::Base.build_client(api_key)
57
+
58
+ # List websets with optional pagination
59
+ list_params = {}
60
+ list_params[:limit] = limit if limit
61
+ list_params[:cursor] = cursor if cursor
62
+
63
+ collection = client.list_websets(**list_params)
64
+
65
+ # Format and output
66
+ output = Exa::CLI::Formatters::WebsetFormatter.format_collection(collection, output_format)
67
+ puts output
68
+
69
+ rescue Exa::ConfigurationError => e
70
+ $stderr.puts "Configuration error: #{e.message}"
71
+ exit 1
72
+ rescue Exa::Unauthorized => e
73
+ $stderr.puts "Authentication error: #{e.message}"
74
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
75
+ exit 1
76
+ rescue Exa::ClientError => e
77
+ $stderr.puts "Client error: #{e.message}"
78
+ exit 1
79
+ rescue Exa::ServerError => e
80
+ $stderr.puts "Server error: #{e.message}"
81
+ $stderr.puts "The Exa API may be experiencing issues. Please try again later."
82
+ exit 1
83
+ rescue Exa::Error => e
84
+ $stderr.puts "Error: #{e.message}"
85
+ exit 1
86
+ rescue StandardError => e
87
+ $stderr.puts "Unexpected error: #{e.message}"
88
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
89
+ exit 1
90
+ end
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Parse arguments
7
+ webset_id = nil
8
+ search_id = nil
9
+ api_key = nil
10
+ output_format = "json"
11
+
12
+ args = ARGV.dup
13
+ while args.any?
14
+ arg = args.shift
15
+ case arg
16
+ when "--api-key"
17
+ api_key = args.shift
18
+ when "--output-format"
19
+ output_format = args.shift
20
+ when "--help", "-h"
21
+ puts <<~HELP
22
+ Usage: exa-ai webset-search-cancel <webset_id> <search_id> [OPTIONS]
23
+
24
+ Cancel a running webset search
25
+
26
+ Arguments:
27
+ webset_id ID of the webset (required)
28
+ search_id ID of the search (required)
29
+
30
+ Options:
31
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
32
+ --output-format FMT Output format: json, pretty, or text (default: json)
33
+ --help, -h Show this help message
34
+
35
+ Examples:
36
+ exa-ai webset-search-cancel ws_123 search_456
37
+ exa-ai webset-search-cancel ws_123 search_456 --output-format text
38
+ HELP
39
+ exit 0
40
+ else
41
+ # First positional argument is webset_id, second is search_id
42
+ if webset_id.nil?
43
+ webset_id = arg
44
+ elsif search_id.nil?
45
+ search_id = arg
46
+ else
47
+ $stderr.puts "Unknown option: #{arg}"
48
+ exit 1
49
+ end
50
+ end
51
+ end
52
+
53
+ # Validate
54
+ if webset_id.nil?
55
+ $stderr.puts "Error: webset_id argument is required"
56
+ $stderr.puts "Usage: exa-ai webset-search-cancel <webset_id> <search_id> [OPTIONS]"
57
+ $stderr.puts "Try 'exa-ai webset-search-cancel --help' for more information"
58
+ exit 1
59
+ end
60
+
61
+ if search_id.nil?
62
+ $stderr.puts "Error: search_id argument is required"
63
+ $stderr.puts "Usage: exa-ai webset-search-cancel <webset_id> <search_id> [OPTIONS]"
64
+ $stderr.puts "Try 'exa-ai webset-search-cancel --help' for more information"
65
+ exit 1
66
+ end
67
+
68
+ begin
69
+ # Resolve API key and format
70
+ api_key = Exa::CLI::Base.resolve_api_key(api_key)
71
+ output_format = Exa::CLI::Base.resolve_output_format(output_format)
72
+
73
+ # Build client
74
+ client = Exa::CLI::Base.build_client(api_key)
75
+
76
+ # Cancel search
77
+ search = client.cancel_webset_search(webset_id: webset_id, id: search_id)
78
+
79
+ # Format and output
80
+ output = Exa::CLI::Formatters::WebsetSearchFormatter.format(search, output_format)
81
+ puts output
82
+
83
+ rescue Exa::NotFound => e
84
+ $stderr.puts "Search not found: #{e.message}"
85
+ exit 1
86
+ rescue Exa::Unauthorized => e
87
+ $stderr.puts "Authentication error: #{e.message}"
88
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
89
+ exit 1
90
+ rescue Exa::ClientError => e
91
+ $stderr.puts "Client error: #{e.message}"
92
+ exit 1
93
+ rescue Exa::ServerError => e
94
+ $stderr.puts "Server error: #{e.message}"
95
+ exit 1
96
+ rescue Exa::Error => e
97
+ $stderr.puts "Error: #{e.message}"
98
+ exit 1
99
+ rescue StandardError => e
100
+ $stderr.puts "Unexpected error: #{e.message}"
101
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
102
+ exit 1
103
+ end
@@ -0,0 +1,233 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Recursively convert hash keys from strings to symbols
7
+ def deep_symbolize_keys(obj)
8
+ case obj
9
+ when Hash
10
+ obj.each_with_object({}) do |(key, value), result|
11
+ result[key.to_sym] = deep_symbolize_keys(value)
12
+ end
13
+ when Array
14
+ obj.map { |item| deep_symbolize_keys(item) }
15
+ else
16
+ obj
17
+ end
18
+ end
19
+
20
+ # Parse JSON string or load from file (supports @file.json syntax)
21
+ def parse_json_or_file(value)
22
+ json_data = if value.start_with?("@")
23
+ file_path = value[1..]
24
+ JSON.parse(File.read(file_path))
25
+ else
26
+ JSON.parse(value)
27
+ end
28
+ deep_symbolize_keys(json_data)
29
+ rescue JSON::ParserError => e
30
+ $stderr.puts "Error: Invalid JSON: #{e.message}"
31
+ exit 1
32
+ rescue Errno::ENOENT => e
33
+ $stderr.puts "Error: File not found: #{e.message}"
34
+ exit 1
35
+ end
36
+
37
+ # Parse command-line arguments
38
+ def parse_args(argv)
39
+ args = {
40
+ output_format: "json",
41
+ api_key: nil
42
+ }
43
+
44
+ # First positional argument is webset_id
45
+ webset_id_found = false
46
+
47
+ i = 0
48
+ while i < argv.length
49
+ arg = argv[i]
50
+ case arg
51
+ when "--query"
52
+ args[:query] = argv[i + 1]
53
+ i += 2
54
+ when "--count"
55
+ args[:count] = argv[i + 1].to_i
56
+ i += 2
57
+ when "--entity"
58
+ args[:entity] = argv[i + 1]
59
+ i += 2
60
+ when "--entity-description"
61
+ args[:entity_description] = argv[i + 1]
62
+ i += 2
63
+ when "--criteria"
64
+ args[:criteria] = parse_json_or_file(argv[i + 1])
65
+ i += 2
66
+ when "--exclude"
67
+ args[:exclude] = parse_json_or_file(argv[i + 1])
68
+ i += 2
69
+ when "--scope"
70
+ args[:scope] = parse_json_or_file(argv[i + 1])
71
+ i += 2
72
+ when "--recall"
73
+ args[:recall] = true
74
+ i += 1
75
+ when "--behavior"
76
+ behavior = argv[i + 1]
77
+ unless ["override", "append"].include?(behavior)
78
+ $stderr.puts "Error: Behavior must be 'override' or 'append'"
79
+ exit 1
80
+ end
81
+ args[:behavior] = behavior
82
+ i += 2
83
+ when "--metadata"
84
+ args[:metadata] = parse_json_or_file(argv[i + 1])
85
+ i += 2
86
+ when "--api-key"
87
+ args[:api_key] = argv[i + 1]
88
+ i += 2
89
+ when "--output-format"
90
+ args[:output_format] = argv[i + 1]
91
+ i += 2
92
+ when "--help", "-h"
93
+ puts <<~HELP
94
+ Usage: exa-ai webset-search-create <webset_id> [OPTIONS]
95
+
96
+ Create a new search within a webset
97
+
98
+ Arguments:
99
+ webset_id ID of the webset (required)
100
+
101
+ Options:
102
+ --query QUERY Search query (required)
103
+ --count N Number of results to find
104
+ --entity TYPE Entity type: person, company, article, research_paper, custom
105
+ --entity-description TXT Description for custom entity type (required with --entity custom)
106
+ --criteria JSON Search criteria array (supports @file.json)
107
+ --exclude JSON Items to exclude from results (supports @file.json)
108
+ --scope JSON Limit search to specific sources (supports @file.json)
109
+ --recall Estimate total available results
110
+ --behavior TYPE "override" or "append" (default: override)
111
+ --metadata JSON Custom metadata (supports @file.json)
112
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
113
+ --output-format FMT Output format: json, pretty, or text (default: json)
114
+ --help, -h Show this help message
115
+
116
+ Examples:
117
+ # Basic search
118
+ exa-ai webset-search-create ws_123 --query "AI startups"
119
+
120
+ # Search with entity type
121
+ exa-ai webset-search-create ws_123 --query "tech CEOs" --entity person
122
+ exa-ai webset-search-create ws_123 --query "Silicon Valley firms" --entity company
123
+
124
+ # Search with custom entity type
125
+ exa-ai webset-search-create ws_123 --query "Ford Mustang" \\
126
+ --entity custom --entity-description "vintage cars"
127
+
128
+ # Other options
129
+ exa-ai webset-search-create ws_123 --query "machine learning" --count 50
130
+ exa-ai webset-search-create ws_123 --query "research" --behavior append --recall
131
+ HELP
132
+ exit 0
133
+ else
134
+ # First positional argument is webset_id
135
+ unless webset_id_found
136
+ args[:webset_id] = arg
137
+ webset_id_found = true
138
+ else
139
+ $stderr.puts "Unknown option: #{arg}"
140
+ exit 1
141
+ end
142
+ i += 1
143
+ end
144
+ end
145
+
146
+ args
147
+ end
148
+
149
+ # Main execution
150
+ begin
151
+ args = parse_args(ARGV)
152
+
153
+ # Validate required parameters
154
+ unless args[:webset_id]
155
+ $stderr.puts "Error: webset_id argument is required"
156
+ $stderr.puts "Run 'exa-ai webset-search-create --help' for usage information"
157
+ exit 1
158
+ end
159
+
160
+ unless args[:query]
161
+ $stderr.puts "Error: --query is required"
162
+ $stderr.puts "Run 'exa-ai webset-search-create --help' for usage information"
163
+ exit 1
164
+ end
165
+
166
+ # Resolve API key
167
+ api_key = Exa::CLI::Base.resolve_api_key(args[:api_key])
168
+
169
+ # Resolve output format
170
+ output_format = Exa::CLI::Base.resolve_output_format(args[:output_format])
171
+
172
+ # Build client
173
+ client = Exa::CLI::Base.build_client(api_key)
174
+
175
+ # Build entity parameter from --entity and --entity-description
176
+ entity = nil
177
+ if args[:entity]
178
+ # Build entity hash from string type
179
+ entity = { type: args[:entity] }
180
+ if args[:entity] == "custom"
181
+ unless args[:entity_description]
182
+ $stderr.puts "Error: --entity-description is required when --entity is 'custom'"
183
+ exit 1
184
+ end
185
+ entity[:description] = args[:entity_description]
186
+ elsif args[:entity_description]
187
+ $stderr.puts "Warning: --entity-description is only used with --entity custom (ignoring)"
188
+ end
189
+ end
190
+
191
+ # Prepare search parameters
192
+ search_params = { query: args[:query] }
193
+ search_params[:count] = args[:count] if args[:count]
194
+ search_params[:entity] = entity if entity
195
+ search_params[:criteria] = args[:criteria] if args[:criteria]
196
+ search_params[:exclude] = args[:exclude] if args[:exclude]
197
+ search_params[:scope] = args[:scope] if args[:scope]
198
+ search_params[:recall] = args[:recall] if args[:recall]
199
+ search_params[:behavior] = args[:behavior] if args[:behavior]
200
+ search_params[:metadata] = args[:metadata] if args[:metadata]
201
+
202
+ # Create search
203
+ search = client.create_webset_search(webset_id: args[:webset_id], **search_params)
204
+
205
+ # Format and output result
206
+ output = Exa::CLI::Formatters::WebsetSearchFormatter.format(search, output_format)
207
+ puts output
208
+
209
+ rescue Exa::ConfigurationError => e
210
+ $stderr.puts "Configuration error: #{e.message}"
211
+ exit 1
212
+ rescue Exa::Unauthorized => e
213
+ $stderr.puts "Authentication error: #{e.message}"
214
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
215
+ exit 1
216
+ rescue Exa::NotFound => e
217
+ $stderr.puts "Webset not found: #{e.message}"
218
+ exit 1
219
+ rescue Exa::ClientError => e
220
+ $stderr.puts "Client error: #{e.message}"
221
+ exit 1
222
+ rescue Exa::ServerError => e
223
+ $stderr.puts "Server error: #{e.message}"
224
+ $stderr.puts "The Exa API may be experiencing issues. Please try again later."
225
+ exit 1
226
+ rescue Exa::Error => e
227
+ $stderr.puts "Error: #{e.message}"
228
+ exit 1
229
+ rescue StandardError => e
230
+ $stderr.puts "Unexpected error: #{e.message}"
231
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
232
+ exit 1
233
+ end
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Parse arguments
7
+ webset_id = nil
8
+ search_id = nil
9
+ api_key = nil
10
+ output_format = "json"
11
+
12
+ args = ARGV.dup
13
+ while args.any?
14
+ arg = args.shift
15
+ case arg
16
+ when "--api-key"
17
+ api_key = args.shift
18
+ when "--output-format"
19
+ output_format = args.shift
20
+ when "--help", "-h"
21
+ puts <<~HELP
22
+ Usage: exa-ai webset-search-get <webset_id> <search_id> [OPTIONS]
23
+
24
+ Get details of a webset search
25
+
26
+ Arguments:
27
+ webset_id ID of the webset (required)
28
+ search_id ID of the search (required)
29
+
30
+ Options:
31
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
32
+ --output-format FMT Output format: json, pretty, or text (default: json)
33
+ --help, -h Show this help message
34
+
35
+ Examples:
36
+ exa-ai webset-search-get ws_123 search_456
37
+ exa-ai webset-search-get ws_123 search_456 --output-format pretty
38
+ exa-ai webset-search-get ws_123 search_456 --output-format text
39
+ HELP
40
+ exit 0
41
+ else
42
+ # First positional argument is webset_id, second is search_id
43
+ if webset_id.nil?
44
+ webset_id = arg
45
+ elsif search_id.nil?
46
+ search_id = arg
47
+ else
48
+ $stderr.puts "Unknown option: #{arg}"
49
+ exit 1
50
+ end
51
+ end
52
+ end
53
+
54
+ # Validate
55
+ if webset_id.nil?
56
+ $stderr.puts "Error: webset_id argument is required"
57
+ $stderr.puts "Usage: exa-ai webset-search-get <webset_id> <search_id> [OPTIONS]"
58
+ $stderr.puts "Try 'exa-ai webset-search-get --help' for more information"
59
+ exit 1
60
+ end
61
+
62
+ if search_id.nil?
63
+ $stderr.puts "Error: search_id argument is required"
64
+ $stderr.puts "Usage: exa-ai webset-search-get <webset_id> <search_id> [OPTIONS]"
65
+ $stderr.puts "Try 'exa-ai webset-search-get --help' for more information"
66
+ exit 1
67
+ end
68
+
69
+ begin
70
+ # Resolve API key and format
71
+ api_key = Exa::CLI::Base.resolve_api_key(api_key)
72
+ output_format = Exa::CLI::Base.resolve_output_format(output_format)
73
+
74
+ # Build client
75
+ client = Exa::CLI::Base.build_client(api_key)
76
+
77
+ # Get search
78
+ search = client.get_webset_search(webset_id: webset_id, id: search_id)
79
+
80
+ # Format and output
81
+ output = Exa::CLI::Formatters::WebsetSearchFormatter.format(search, output_format)
82
+ puts output
83
+
84
+ rescue Exa::NotFound => e
85
+ $stderr.puts "Search not found: #{e.message}"
86
+ exit 1
87
+ rescue Exa::Unauthorized => e
88
+ $stderr.puts "Authentication error: #{e.message}"
89
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
90
+ exit 1
91
+ rescue Exa::ClientError => e
92
+ $stderr.puts "Client error: #{e.message}"
93
+ exit 1
94
+ rescue Exa::ServerError => e
95
+ $stderr.puts "Server error: #{e.message}"
96
+ exit 1
97
+ rescue Exa::Error => e
98
+ $stderr.puts "Error: #{e.message}"
99
+ exit 1
100
+ rescue StandardError => e
101
+ $stderr.puts "Unexpected error: #{e.message}"
102
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
103
+ exit 1
104
+ end