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.
- checksums.yaml +4 -4
- data/README.md +94 -591
- data/exe/exa-ai +112 -9
- data/exe/exa-ai-answer +1 -5
- data/exe/exa-ai-context +1 -4
- data/exe/exa-ai-enrichment-cancel +107 -0
- data/exe/exa-ai-enrichment-create +235 -0
- data/exe/exa-ai-enrichment-delete +121 -0
- data/exe/exa-ai-enrichment-get +103 -0
- data/exe/exa-ai-enrichment-list +98 -0
- data/exe/exa-ai-enrichment-update +170 -0
- data/exe/exa-ai-find-similar +240 -0
- data/exe/exa-ai-get-contents +1 -4
- data/exe/exa-ai-research-get +1 -2
- data/exe/exa-ai-research-list +1 -2
- data/exe/exa-ai-research-start +1 -3
- data/exe/exa-ai-search +1 -3
- data/exe/exa-ai-webset-cancel +96 -0
- data/exe/exa-ai-webset-create +192 -0
- data/exe/exa-ai-webset-delete +110 -0
- data/exe/exa-ai-webset-get +92 -0
- data/exe/exa-ai-webset-item-delete +111 -0
- data/exe/exa-ai-webset-item-get +104 -0
- data/exe/exa-ai-webset-item-list +93 -0
- data/exe/exa-ai-webset-list +90 -0
- data/exe/exa-ai-webset-search-cancel +103 -0
- data/exe/exa-ai-webset-search-create +233 -0
- data/exe/exa-ai-webset-search-get +104 -0
- data/exe/exa-ai-webset-update +139 -0
- data/lib/exa/cli/base.rb +3 -3
- data/lib/exa/cli/formatters/enrichment_formatter.rb +69 -0
- data/lib/exa/cli/formatters/webset_formatter.rb +68 -0
- data/lib/exa/cli/formatters/webset_item_formatter.rb +69 -0
- data/lib/exa/client.rb +172 -0
- data/lib/exa/connection.rb +8 -1
- data/lib/exa/resources/webset.rb +74 -0
- data/lib/exa/resources/webset_collection.rb +33 -0
- data/lib/exa/resources/webset_enrichment.rb +71 -0
- data/lib/exa/resources/webset_enrichment_collection.rb +28 -0
- data/lib/exa/resources/webset_search.rb +112 -0
- data/lib/exa/services/parameter_converter.rb +1 -0
- data/lib/exa/services/websets/cancel.rb +36 -0
- data/lib/exa/services/websets/cancel_enrichment.rb +35 -0
- data/lib/exa/services/websets/cancel_search.rb +44 -0
- data/lib/exa/services/websets/create.rb +45 -0
- data/lib/exa/services/websets/create_enrichment.rb +35 -0
- data/lib/exa/services/websets/create_search.rb +48 -0
- data/lib/exa/services/websets/create_search_validator.rb +128 -0
- data/lib/exa/services/websets/create_validator.rb +189 -0
- data/lib/exa/services/websets/delete.rb +36 -0
- data/lib/exa/services/websets/delete_enrichment.rb +35 -0
- data/lib/exa/services/websets/delete_item.rb +20 -0
- data/lib/exa/services/websets/get_item.rb +20 -0
- data/lib/exa/services/websets/get_search.rb +43 -0
- data/lib/exa/services/websets/list.rb +25 -0
- data/lib/exa/services/websets/list_items.rb +20 -0
- data/lib/exa/services/websets/retrieve.rb +47 -0
- data/lib/exa/services/websets/retrieve_enrichment.rb +35 -0
- data/lib/exa/services/websets/update.rb +37 -0
- data/lib/exa/services/websets/update_enrichment.rb +36 -0
- data/lib/exa/services/websets_parameter_converter.rb +45 -0
- data/lib/exa/version.rb +1 -1
- data/lib/exa-ai.rb +5 -0
- data/lib/exa.rb +26 -0
- 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
|