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,96 @@
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-cancel <webset_id> [OPTIONS]
22
+
23
+ Cancel a running webset
24
+
25
+ Arguments:
26
+ webset_id ID of the webset to cancel (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-cancel ws_abc123
35
+ exa-ai webset-cancel ws_abc123 --output-format pretty
36
+ HELP
37
+ exit 0
38
+ else
39
+ # First positional argument is webset_id
40
+ if webset_id.nil?
41
+ webset_id = arg
42
+ else
43
+ $stderr.puts "Unknown option: #{arg}"
44
+ exit 1
45
+ end
46
+ end
47
+ end
48
+
49
+ # Validate
50
+ if webset_id.nil?
51
+ $stderr.puts "Error: webset_id argument is required"
52
+ $stderr.puts "Usage: exa-ai webset-cancel <webset_id> [OPTIONS]"
53
+ $stderr.puts "Try 'exa-ai webset-cancel --help' for more information"
54
+ exit 1
55
+ end
56
+
57
+ begin
58
+ # Resolve API key and format
59
+ api_key = Exa::CLI::Base.resolve_api_key(api_key)
60
+ output_format = Exa::CLI::Base.resolve_output_format(output_format)
61
+
62
+ # Build client
63
+ client = Exa::CLI::Base.build_client(api_key)
64
+
65
+ # Cancel webset
66
+ webset = client.cancel_webset(webset_id)
67
+
68
+ # Format and output
69
+ output = Exa::CLI::Formatters::WebsetFormatter.format(webset, output_format)
70
+ puts output
71
+
72
+ rescue Exa::NotFound => e
73
+ $stderr.puts "Webset not found: #{e.message}"
74
+ exit 1
75
+ rescue Exa::ConfigurationError => e
76
+ $stderr.puts "Configuration error: #{e.message}"
77
+ exit 1
78
+ rescue Exa::Unauthorized => e
79
+ $stderr.puts "Authentication error: #{e.message}"
80
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
81
+ exit 1
82
+ rescue Exa::ClientError => e
83
+ $stderr.puts "Client error: #{e.message}"
84
+ exit 1
85
+ rescue Exa::ServerError => e
86
+ $stderr.puts "Server error: #{e.message}"
87
+ $stderr.puts "The Exa API may be experiencing issues. Please try again later."
88
+ exit 1
89
+ rescue Exa::Error => e
90
+ $stderr.puts "Error: #{e.message}"
91
+ exit 1
92
+ rescue StandardError => e
93
+ $stderr.puts "Unexpected error: #{e.message}"
94
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
95
+ exit 1
96
+ end
@@ -0,0 +1,192 @@
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
+ wait: false
43
+ }
44
+
45
+ i = 0
46
+ while i < argv.length
47
+ arg = argv[i]
48
+ case arg
49
+ when "--search"
50
+ args[:search] = parse_json_or_file(argv[i + 1])
51
+ i += 2
52
+ when "--enrichments"
53
+ args[:enrichments] = parse_json_or_file(argv[i + 1])
54
+ i += 2
55
+ when "--exclude"
56
+ args[:exclude] = parse_json_or_file(argv[i + 1])
57
+ i += 2
58
+ when "--external-id"
59
+ args[:external_id] = argv[i + 1]
60
+ i += 2
61
+ when "--metadata"
62
+ args[:metadata] = parse_json_or_file(argv[i + 1])
63
+ i += 2
64
+ when "--wait"
65
+ args[:wait] = true
66
+ i += 1
67
+ when "--api-key"
68
+ args[:api_key] = argv[i + 1]
69
+ i += 2
70
+ when "--output-format"
71
+ args[:output_format] = argv[i + 1]
72
+ i += 2
73
+ when "--help", "-h"
74
+ puts <<~HELP
75
+ Usage: exa-ai webset-create --search JSON [OPTIONS]
76
+
77
+ Create a new webset with search criteria
78
+
79
+ Required:
80
+ --search JSON Search configuration (supports @file.json)
81
+
82
+ Options:
83
+ --enrichments JSON Array of enrichment configs (supports @file.json)
84
+ --exclude JSON Array of exclude configs (supports @file.json)
85
+ --external-id ID External identifier for the webset
86
+ --metadata JSON Custom metadata (supports @file.json)
87
+ --wait Wait for webset to reach idle status
88
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
89
+ --output-format FMT Output format: json, pretty, or text (default: json)
90
+ --help, -h Show this help message
91
+
92
+ Examples:
93
+ exa-ai webset-create --search '{"query":"AI startups","count":10}'
94
+ exa-ai webset-create --search @search.json --enrichments @enrichments.json
95
+ exa-ai webset-create --search @search.json --wait
96
+ HELP
97
+ exit 0
98
+ else
99
+ $stderr.puts "Unknown option: #{arg}"
100
+ exit 1
101
+ end
102
+ end
103
+
104
+ args
105
+ end
106
+
107
+ # Main execution
108
+ begin
109
+ args = parse_args(ARGV)
110
+
111
+ # Validate required parameters
112
+ unless args[:search]
113
+ $stderr.puts "Error: --search is required"
114
+ $stderr.puts "Run 'exa-ai webset-create --help' for usage information"
115
+ exit 1
116
+ end
117
+
118
+ # Resolve API key
119
+ api_key = Exa::CLI::Base.resolve_api_key(args[:api_key])
120
+
121
+ # Resolve output format
122
+ output_format = Exa::CLI::Base.resolve_output_format(args[:output_format])
123
+
124
+ # Build client
125
+ client = Exa::CLI::Base.build_client(api_key)
126
+
127
+ # Prepare webset parameters
128
+ webset_params = { search: args[:search] }
129
+ webset_params[:enrichments] = args[:enrichments] if args[:enrichments]
130
+ webset_params[:exclude] = args[:exclude] if args[:exclude]
131
+ webset_params[:externalId] = args[:external_id] if args[:external_id]
132
+ webset_params[:metadata] = args[:metadata] if args[:metadata]
133
+
134
+ # Create webset
135
+ webset = client.create_webset(**webset_params)
136
+
137
+ # If --wait flag is set, poll until webset is idle
138
+ if args[:wait]
139
+ $stderr.print "Creating webset... "
140
+
141
+ begin
142
+ final_webset = Exa::CLI::Polling.poll(max_duration: 300, initial_delay: 2, max_delay: 10) do
143
+ current_webset = client.get_webset(webset.id)
144
+
145
+ # Show progress indicator
146
+ case current_webset.status
147
+ when "pending"
148
+ $stderr.print "⏳"
149
+ when "running"
150
+ $stderr.print "⚙️"
151
+ end
152
+
153
+ done = current_webset.idle?
154
+ { done: done, result: current_webset, status: current_webset.status }
155
+ end
156
+
157
+ $stderr.puts " #{final_webset.status.upcase}"
158
+ webset = final_webset
159
+
160
+ rescue Exa::CLI::Polling::TimeoutError
161
+ $stderr.puts "\nWarning: Webset creation did not complete within timeout"
162
+ $stderr.puts "Webset ID: #{webset.id}"
163
+ $stderr.puts "Check status with: exa-ai webset-get #{webset.id}"
164
+ end
165
+ end
166
+
167
+ # Format and output result
168
+ output = Exa::CLI::Formatters::WebsetFormatter.format(webset, output_format)
169
+ puts output
170
+
171
+ rescue Exa::ConfigurationError => e
172
+ $stderr.puts "Configuration error: #{e.message}"
173
+ exit 1
174
+ rescue Exa::Unauthorized => e
175
+ $stderr.puts "Authentication error: #{e.message}"
176
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
177
+ exit 1
178
+ rescue Exa::ClientError => e
179
+ $stderr.puts "Client error: #{e.message}"
180
+ exit 1
181
+ rescue Exa::ServerError => e
182
+ $stderr.puts "Server error: #{e.message}"
183
+ $stderr.puts "The Exa API may be experiencing issues. Please try again later."
184
+ exit 1
185
+ rescue Exa::Error => e
186
+ $stderr.puts "Error: #{e.message}"
187
+ exit 1
188
+ rescue StandardError => e
189
+ $stderr.puts "Unexpected error: #{e.message}"
190
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
191
+ exit 1
192
+ end
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Parse arguments
7
+ webset_id = nil
8
+ force = false
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 "--force"
17
+ force = true
18
+ when "--api-key"
19
+ api_key = args.shift
20
+ when "--output-format"
21
+ output_format = args.shift
22
+ when "--help", "-h"
23
+ puts <<~HELP
24
+ Usage: exa-ai webset-delete <webset_id> [OPTIONS]
25
+
26
+ Delete a webset
27
+
28
+ Arguments:
29
+ webset_id ID of the webset to delete (required)
30
+
31
+ Options:
32
+ --force Skip confirmation prompt
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-delete ws_abc123
39
+ exa-ai webset-delete ws_abc123 --force
40
+ HELP
41
+ exit 0
42
+ else
43
+ # First positional argument is webset_id
44
+ if webset_id.nil?
45
+ webset_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-delete <webset_id> [OPTIONS]"
57
+ $stderr.puts "Try 'exa-ai webset-delete --help' for more information"
58
+ exit 1
59
+ end
60
+
61
+ begin
62
+ # Resolve API key and format
63
+ api_key = Exa::CLI::Base.resolve_api_key(api_key)
64
+ output_format = Exa::CLI::Base.resolve_output_format(output_format)
65
+
66
+ # Confirm deletion unless --force is used
67
+ unless force
68
+ $stderr.print "Delete webset #{webset_id}? (y/N): "
69
+ response = $stdin.gets.chomp.downcase
70
+ unless response == "y" || response == "yes"
71
+ $stderr.puts "Cancelled"
72
+ exit 0
73
+ end
74
+ end
75
+
76
+ # Build client
77
+ client = Exa::CLI::Base.build_client(api_key)
78
+
79
+ # Delete webset
80
+ result = client.delete_webset(webset_id)
81
+
82
+ # Format and output
83
+ output = Exa::CLI::Formatters::WebsetFormatter.format(result, output_format)
84
+ puts output
85
+
86
+ rescue Exa::NotFound => e
87
+ $stderr.puts "Webset not found: #{e.message}"
88
+ exit 1
89
+ rescue Exa::ConfigurationError => e
90
+ $stderr.puts "Configuration error: #{e.message}"
91
+ exit 1
92
+ rescue Exa::Unauthorized => e
93
+ $stderr.puts "Authentication error: #{e.message}"
94
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
95
+ exit 1
96
+ rescue Exa::ClientError => e
97
+ $stderr.puts "Client error: #{e.message}"
98
+ exit 1
99
+ rescue Exa::ServerError => e
100
+ $stderr.puts "Server error: #{e.message}"
101
+ $stderr.puts "The Exa API may be experiencing issues. Please try again later."
102
+ exit 1
103
+ rescue Exa::Error => e
104
+ $stderr.puts "Error: #{e.message}"
105
+ exit 1
106
+ rescue StandardError => e
107
+ $stderr.puts "Unexpected error: #{e.message}"
108
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
109
+ exit 1
110
+ end
@@ -0,0 +1,92 @@
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-get <webset_id> [OPTIONS]
22
+
23
+ Retrieve details for a webset
24
+
25
+ Arguments:
26
+ webset_id ID of the webset to retrieve (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-get ws_abc123
35
+ exa-ai webset-get ws_abc123 --output-format pretty
36
+ HELP
37
+ exit 0
38
+ else
39
+ # First positional argument is webset_id
40
+ if webset_id.nil?
41
+ webset_id = arg
42
+ else
43
+ $stderr.puts "Unknown option: #{arg}"
44
+ exit 1
45
+ end
46
+ end
47
+ end
48
+
49
+ # Validate
50
+ if webset_id.nil?
51
+ $stderr.puts "Error: webset_id argument is required"
52
+ $stderr.puts "Usage: exa-ai webset-get <webset_id> [OPTIONS]"
53
+ $stderr.puts "Try 'exa-ai webset-get --help' for more information"
54
+ exit 1
55
+ end
56
+
57
+ begin
58
+ # Resolve API key and format
59
+ api_key = Exa::CLI::Base.resolve_api_key(api_key)
60
+ output_format = Exa::CLI::Base.resolve_output_format(output_format)
61
+
62
+ # Build client
63
+ client = Exa::CLI::Base.build_client(api_key)
64
+
65
+ # Get webset
66
+ webset = client.get_webset(webset_id)
67
+
68
+ # Format and output
69
+ output = Exa::CLI::Formatters::WebsetFormatter.format(webset, output_format)
70
+ puts output
71
+
72
+ rescue Exa::NotFound => e
73
+ $stderr.puts "Webset not found: #{e.message}"
74
+ exit 1
75
+ rescue Exa::Unauthorized => e
76
+ $stderr.puts "Authentication error: #{e.message}"
77
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
78
+ exit 1
79
+ rescue Exa::ClientError => e
80
+ $stderr.puts "Client error: #{e.message}"
81
+ exit 1
82
+ rescue Exa::ServerError => e
83
+ $stderr.puts "Server error: #{e.message}"
84
+ exit 1
85
+ rescue Exa::Error => e
86
+ $stderr.puts "Error: #{e.message}"
87
+ exit 1
88
+ rescue StandardError => e
89
+ $stderr.puts "Unexpected error: #{e.message}"
90
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
91
+ exit 1
92
+ end
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Parse arguments
7
+ webset_id = nil
8
+ item_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-item-delete <webset_id> <item_id> [OPTIONS]
23
+
24
+ Delete a webset item
25
+
26
+ Arguments:
27
+ webset_id ID of the webset (required)
28
+ item_id ID of the item (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-item-delete ws_123 item_456
37
+ exa-ai webset-item-delete ws_123 item_456 --output-format text
38
+ HELP
39
+ exit 0
40
+ else
41
+ # First positional argument is webset_id, second is item_id
42
+ if webset_id.nil?
43
+ webset_id = arg
44
+ elsif item_id.nil?
45
+ item_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-item-delete <webset_id> <item_id> [OPTIONS]"
57
+ $stderr.puts "Try 'exa-ai webset-item-delete --help' for more information"
58
+ exit 1
59
+ end
60
+
61
+ if item_id.nil?
62
+ $stderr.puts "Error: item_id argument is required"
63
+ $stderr.puts "Usage: exa-ai webset-item-delete <webset_id> <item_id> [OPTIONS]"
64
+ $stderr.puts "Try 'exa-ai webset-item-delete --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
+ # Delete item
77
+ result = client.delete_item(webset_id: webset_id, id: item_id)
78
+
79
+ # Format and output
80
+ if result
81
+ case output_format
82
+ when :text
83
+ puts "Item #{item_id} deleted successfully"
84
+ when :pretty
85
+ puts JSON.pretty_generate({ success: true, item_id: item_id })
86
+ else
87
+ puts JSON.generate({ success: true, item_id: item_id })
88
+ end
89
+ end
90
+
91
+ rescue Exa::NotFound => e
92
+ $stderr.puts "Item not found: #{e.message}"
93
+ exit 1
94
+ rescue Exa::Unauthorized => e
95
+ $stderr.puts "Authentication error: #{e.message}"
96
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
97
+ exit 1
98
+ rescue Exa::ClientError => e
99
+ $stderr.puts "Client error: #{e.message}"
100
+ exit 1
101
+ rescue Exa::ServerError => e
102
+ $stderr.puts "Server error: #{e.message}"
103
+ exit 1
104
+ rescue Exa::Error => e
105
+ $stderr.puts "Error: #{e.message}"
106
+ exit 1
107
+ rescue StandardError => e
108
+ $stderr.puts "Unexpected error: #{e.message}"
109
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
110
+ exit 1
111
+ 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
+ item_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-item-get <webset_id> <item_id> [OPTIONS]
23
+
24
+ Get details of a webset item
25
+
26
+ Arguments:
27
+ webset_id ID of the webset (required)
28
+ item_id ID of the item (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-item-get ws_123 item_456
37
+ exa-ai webset-item-get ws_123 item_456 --output-format pretty
38
+ exa-ai webset-item-get ws_123 item_456 --output-format text
39
+ HELP
40
+ exit 0
41
+ else
42
+ # First positional argument is webset_id, second is item_id
43
+ if webset_id.nil?
44
+ webset_id = arg
45
+ elsif item_id.nil?
46
+ item_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-item-get <webset_id> <item_id> [OPTIONS]"
58
+ $stderr.puts "Try 'exa-ai webset-item-get --help' for more information"
59
+ exit 1
60
+ end
61
+
62
+ if item_id.nil?
63
+ $stderr.puts "Error: item_id argument is required"
64
+ $stderr.puts "Usage: exa-ai webset-item-get <webset_id> <item_id> [OPTIONS]"
65
+ $stderr.puts "Try 'exa-ai webset-item-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 item
78
+ item = client.get_item(webset_id: webset_id, id: item_id)
79
+
80
+ # Format and output
81
+ output = Exa::CLI::Formatters::WebsetItemFormatter.format(item, output_format)
82
+ puts output
83
+
84
+ rescue Exa::NotFound => e
85
+ $stderr.puts "Item 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