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
data/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# exa-ruby
|
|
2
2
|
|
|
3
|
-
Ruby client for the Exa.ai API
|
|
4
|
-
|
|
5
|
-
**Status**: Phase 9 CLI implementation complete. All commands working with full option support.
|
|
3
|
+
Ruby client for the Exa.ai API. Search and analyze web content using neural search, question answering, code discovery, and research automation.
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
@@ -26,20 +24,18 @@ gem install exa-ai
|
|
|
26
24
|
|
|
27
25
|
## Configuration
|
|
28
26
|
|
|
29
|
-
### Setting Your API Key
|
|
30
|
-
|
|
31
27
|
Get your API key from [dashboard.exa.ai](https://dashboard.exa.ai).
|
|
32
28
|
|
|
33
|
-
**
|
|
29
|
+
**Environment Variable (recommended)**
|
|
34
30
|
|
|
35
31
|
```bash
|
|
36
32
|
export EXA_API_KEY="your-api-key-here"
|
|
37
33
|
```
|
|
38
34
|
|
|
39
|
-
**
|
|
35
|
+
**Ruby Code**
|
|
40
36
|
|
|
41
37
|
```ruby
|
|
42
|
-
require 'exa'
|
|
38
|
+
require 'exa-ai'
|
|
43
39
|
|
|
44
40
|
Exa.configure do |config|
|
|
45
41
|
config.api_key = "your-api-key-here"
|
|
@@ -49,18 +45,18 @@ end
|
|
|
49
45
|
client = Exa::Client.new(api_key: "your-api-key-here")
|
|
50
46
|
```
|
|
51
47
|
|
|
52
|
-
**
|
|
48
|
+
**CLI Flag**
|
|
53
49
|
|
|
54
50
|
```bash
|
|
55
51
|
exa-ai search "query" --api-key YOUR_API_KEY
|
|
56
52
|
```
|
|
57
53
|
|
|
58
|
-
##
|
|
54
|
+
## Quick Start
|
|
59
55
|
|
|
60
|
-
###
|
|
56
|
+
### Ruby API
|
|
61
57
|
|
|
62
58
|
```ruby
|
|
63
|
-
require 'exa'
|
|
59
|
+
require 'exa-ai'
|
|
64
60
|
|
|
65
61
|
Exa.configure do |config|
|
|
66
62
|
config.api_key = ENV['EXA_API_KEY']
|
|
@@ -69,627 +65,134 @@ end
|
|
|
69
65
|
client = Exa::Client.new
|
|
70
66
|
|
|
71
67
|
# Search the web
|
|
72
|
-
results = client.search("
|
|
73
|
-
|
|
68
|
+
results = client.search("Ruby programming language")
|
|
69
|
+
results.results.each { |item| puts "#{item['title']}: #{item['url']}" }
|
|
70
|
+
|
|
71
|
+
# Find similar content
|
|
72
|
+
similar = client.find_similar("https://arxiv.org/abs/2307.06435")
|
|
73
|
+
similar.results.each { |item| puts item['url'] }
|
|
74
74
|
|
|
75
75
|
# Get an answer to a question
|
|
76
|
-
answer = client.answer("What
|
|
76
|
+
answer = client.answer("What is machine learning?")
|
|
77
77
|
puts answer.answer
|
|
78
|
-
puts answer.citations
|
|
79
78
|
|
|
80
|
-
#
|
|
79
|
+
# Find code examples
|
|
81
80
|
code = client.context("React hooks")
|
|
82
81
|
puts code.response
|
|
83
82
|
|
|
84
|
-
#
|
|
85
|
-
contents = client.get_contents(["https://
|
|
83
|
+
# Get page contents
|
|
84
|
+
contents = client.get_contents(["https://ruby-lang.org"])
|
|
86
85
|
puts contents.results.first["text"]
|
|
87
86
|
```
|
|
88
87
|
|
|
89
|
-
###
|
|
90
|
-
|
|
91
|
-
```ruby
|
|
92
|
-
client = Exa::Client.new(api_key: "your-key")
|
|
93
|
-
|
|
94
|
-
# Basic search
|
|
95
|
-
results = client.search("machine learning")
|
|
96
|
-
|
|
97
|
-
# With options
|
|
98
|
-
results = client.search("AI",
|
|
99
|
-
num_results: 10,
|
|
100
|
-
type: "neural",
|
|
101
|
-
include_domains: ["arxiv.org", "github.com"]
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
# Access results
|
|
105
|
-
results.results.each do |item|
|
|
106
|
-
puts item["title"]
|
|
107
|
-
puts item["url"]
|
|
108
|
-
puts item["score"]
|
|
109
|
-
end
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Answer
|
|
113
|
-
|
|
114
|
-
```ruby
|
|
115
|
-
client = Exa::Client.new(api_key: "your-key")
|
|
116
|
-
|
|
117
|
-
# Get an answer to a question
|
|
118
|
-
answer = client.answer("What are the best practices for API design?")
|
|
119
|
-
|
|
120
|
-
puts answer.answer # The generated answer
|
|
121
|
-
puts answer.citations # Array of source citations
|
|
122
|
-
puts answer.cost_dollars # API cost
|
|
123
|
-
|
|
124
|
-
# With text content from sources
|
|
125
|
-
answer = client.answer("Latest AI breakthroughs", text: true)
|
|
126
|
-
puts answer.answer
|
|
127
|
-
answer.citations.each do |citation|
|
|
128
|
-
puts "#{citation["title"]} (#{citation['url']})"
|
|
129
|
-
end
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### Context (Code Search)
|
|
133
|
-
|
|
134
|
-
```ruby
|
|
135
|
-
code = client.context("authentication in Rails")
|
|
136
|
-
|
|
137
|
-
puts code.response # The code context
|
|
138
|
-
puts code.results_count # Number of results
|
|
139
|
-
puts code.cost_dollars # API cost
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### Get Contents
|
|
143
|
-
|
|
144
|
-
```ruby
|
|
145
|
-
contents = client.get_contents([
|
|
146
|
-
"https://example.com/page1",
|
|
147
|
-
"https://example.com/page2"
|
|
148
|
-
])
|
|
149
|
-
|
|
150
|
-
contents.results.each do |content|
|
|
151
|
-
puts content["url"]
|
|
152
|
-
puts content["title"]
|
|
153
|
-
puts content["text"]
|
|
154
|
-
end
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### Research (Async Tasks)
|
|
158
|
-
|
|
159
|
-
```ruby
|
|
160
|
-
# Start a research task
|
|
161
|
-
task = client.research_start(
|
|
162
|
-
instructions: "Analyze recent AI breakthroughs",
|
|
163
|
-
model: "gpt-4"
|
|
164
|
-
)
|
|
165
|
-
puts task.research_id # Save for later polling
|
|
166
|
-
|
|
167
|
-
# Check status
|
|
168
|
-
status = client.research_get(task.research_id)
|
|
169
|
-
if status.completed?
|
|
170
|
-
puts status.output
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# List all tasks
|
|
174
|
-
list = client.research_list(limit: 20)
|
|
175
|
-
list.data.each do |task|
|
|
176
|
-
puts "#{task.research_id}: #{task.status}"
|
|
177
|
-
end
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## CLI Usage
|
|
181
|
-
|
|
182
|
-
### Main Commands
|
|
88
|
+
### Command Line
|
|
183
89
|
|
|
184
90
|
```bash
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
answer Generate answers to questions
|
|
190
|
-
context Get code context from repositories
|
|
191
|
-
get-contents Retrieve page contents
|
|
192
|
-
research-start Start a research task
|
|
193
|
-
research-get Get research task status
|
|
194
|
-
research-list List research tasks
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### Search Command
|
|
198
|
-
|
|
199
|
-
Search the web using Exa's neural search:
|
|
200
|
-
|
|
201
|
-
```bash
|
|
202
|
-
# Basic search
|
|
203
|
-
exa-ai search "ruby programming"
|
|
204
|
-
|
|
205
|
-
# With options
|
|
206
|
-
exa-ai search "machine learning" --num-results 10 --type keyword
|
|
207
|
-
|
|
208
|
-
# Filter by domains
|
|
209
|
-
exa-ai search "tutorials" \
|
|
210
|
-
--include-domains "github.com,dev.to" \
|
|
211
|
-
--exclude-domains "outdated-site.com"
|
|
212
|
-
|
|
213
|
-
# Pretty output
|
|
214
|
-
exa-ai search "AI" --output-format pretty
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
**Basic Options:**
|
|
218
|
-
- `QUERY` - Search query (required)
|
|
219
|
-
- `--num-results N` - Number of results (default: 10)
|
|
220
|
-
- `--type TYPE` - Search type: keyword, neural, or auto (default: auto)
|
|
221
|
-
- `--include-domains DOMAINS` - Comma-separated domains to include
|
|
222
|
-
- `--exclude-domains DOMAINS` - Comma-separated domains to exclude
|
|
223
|
-
- `--output-format FORMAT` - json or pretty (default: json)
|
|
224
|
-
- `--api-key KEY` - API key (or set EXA_API_KEY env var)
|
|
225
|
-
|
|
226
|
-
#### Advanced Search Options
|
|
227
|
-
|
|
228
|
-
**Date Filtering:**
|
|
229
|
-
```bash
|
|
230
|
-
# Filter by published date
|
|
231
|
-
exa-ai search "AI research" \
|
|
232
|
-
--start-published-date "2025-01-01T00:00:00.000Z" \
|
|
233
|
-
--end-published-date "2025-12-31T23:59:59.999Z"
|
|
234
|
-
|
|
235
|
-
# Filter by crawl date
|
|
236
|
-
exa-ai search "news" \
|
|
237
|
-
--start-crawl-date "2025-10-01T00:00:00.000Z" \
|
|
238
|
-
--end-crawl-date "2025-10-31T23:59:59.999Z"
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
**Text Filtering:**
|
|
242
|
-
```bash
|
|
243
|
-
# Results must include specific phrase
|
|
244
|
-
exa-ai search "machine learning" --include-text "neural networks"
|
|
245
|
-
|
|
246
|
-
# Results must exclude specific phrase
|
|
247
|
-
exa-ai search "programming" --exclude-text "paid-partnership"
|
|
248
|
-
|
|
249
|
-
# Combine inclusion and exclusion
|
|
250
|
-
exa-ai search "Python" \
|
|
251
|
-
--include-text "open source" \
|
|
252
|
-
--exclude-text "deprecated"
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
**Content Extraction:**
|
|
256
|
-
```bash
|
|
257
|
-
# Extract full webpage text
|
|
258
|
-
exa-ai search "Ruby" --text
|
|
259
|
-
|
|
260
|
-
# Extract text with options
|
|
261
|
-
exa-ai search "AI" \
|
|
262
|
-
--text \
|
|
263
|
-
--text-max-characters 3000 \
|
|
264
|
-
--include-html-tags
|
|
265
|
-
|
|
266
|
-
# Generate AI summaries
|
|
267
|
-
exa-ai search "climate change" \
|
|
268
|
-
--summary \
|
|
269
|
-
--summary-query "What are the main points?"
|
|
270
|
-
|
|
271
|
-
# Format results as context for LLM RAG
|
|
272
|
-
exa-ai search "kubernetes" \
|
|
273
|
-
--context \
|
|
274
|
-
--context-max-characters 5000
|
|
275
|
-
|
|
276
|
-
# Crawl subpages
|
|
277
|
-
exa-ai search "documentation" \
|
|
278
|
-
--subpages 1 \
|
|
279
|
-
--subpage-target about \
|
|
280
|
-
--subpage-target docs
|
|
281
|
-
|
|
282
|
-
# Extract links from results
|
|
283
|
-
exa-ai search "web development" \
|
|
284
|
-
--links 3 \
|
|
285
|
-
--image-links 2
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
**Advanced Ruby API:**
|
|
289
|
-
```ruby
|
|
290
|
-
client = Exa::Client.new(api_key: "your-key")
|
|
291
|
-
|
|
292
|
-
# Date range filtering
|
|
293
|
-
results = client.search("AI research",
|
|
294
|
-
start_published_date: "2025-01-01T00:00:00.000Z",
|
|
295
|
-
end_published_date: "2025-12-31T23:59:59.999Z"
|
|
296
|
-
)
|
|
297
|
-
|
|
298
|
-
# Text filtering
|
|
299
|
-
results = client.search("machine learning",
|
|
300
|
-
include_text: ["neural networks"],
|
|
301
|
-
exclude_text: ["cryptocurrency"]
|
|
302
|
-
)
|
|
303
|
-
|
|
304
|
-
# Full webpage text extraction
|
|
305
|
-
results = client.search("Ruby",
|
|
306
|
-
text: {
|
|
307
|
-
max_characters: 3000,
|
|
308
|
-
include_html_tags: true
|
|
309
|
-
}
|
|
310
|
-
)
|
|
311
|
-
|
|
312
|
-
# AI-powered summaries
|
|
313
|
-
results = client.search("climate change",
|
|
314
|
-
summary: {
|
|
315
|
-
query: "What are the main points?"
|
|
316
|
-
}
|
|
317
|
-
)
|
|
318
|
-
|
|
319
|
-
# Context for RAG pipelines
|
|
320
|
-
results = client.search("kubernetes",
|
|
321
|
-
context: {
|
|
322
|
-
max_characters: 5000
|
|
323
|
-
}
|
|
324
|
-
)
|
|
325
|
-
|
|
326
|
-
# Subpage crawling
|
|
327
|
-
results = client.search("documentation",
|
|
328
|
-
subpages: 1,
|
|
329
|
-
subpage_target: ["about", "docs", "guide"]
|
|
330
|
-
)
|
|
331
|
-
|
|
332
|
-
# Links and image extraction
|
|
333
|
-
results = client.search("web development",
|
|
334
|
-
extras: {
|
|
335
|
-
links: 3,
|
|
336
|
-
image_links: 2
|
|
337
|
-
}
|
|
338
|
-
)
|
|
339
|
-
|
|
340
|
-
# Combine multiple features
|
|
341
|
-
results = client.search("AI",
|
|
342
|
-
num_results: 5,
|
|
343
|
-
start_published_date: "2025-01-01T00:00:00.000Z",
|
|
344
|
-
text: { max_characters: 3000 },
|
|
345
|
-
summary: { query: "Main developments?" },
|
|
346
|
-
context: { max_characters: 5000 },
|
|
347
|
-
subpages: 1,
|
|
348
|
-
subpage_target: ["research"],
|
|
349
|
-
extras: { links: 3, image_links: 2 }
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
# Access extracted content
|
|
353
|
-
results.results.each do |result|
|
|
354
|
-
puts result["title"]
|
|
355
|
-
puts result["text"] if result["text"] # Full webpage text
|
|
356
|
-
puts result["summary"] if result["summary"] # AI summary
|
|
357
|
-
puts result["links"] if result["links"] # Extracted links
|
|
358
|
-
end
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### Answer Command
|
|
362
|
-
|
|
363
|
-
Generate comprehensive answers to questions using Exa's answer generation feature:
|
|
364
|
-
|
|
365
|
-
```bash
|
|
366
|
-
# Basic question
|
|
367
|
-
exa-ai answer "What is the capital of France?"
|
|
368
|
-
|
|
369
|
-
# Get answer with source citations
|
|
370
|
-
exa-ai answer "Latest developments in quantum computing"
|
|
371
|
-
|
|
372
|
-
# Include full text from sources
|
|
373
|
-
exa-ai answer "Ruby on Rails best practices" --text
|
|
374
|
-
|
|
375
|
-
# Pretty formatted output
|
|
376
|
-
exa-ai answer "How do I learn machine learning?" --output-format pretty
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
**Options:**
|
|
380
|
-
- `QUERY` - Question to answer (required)
|
|
381
|
-
- `--text` - Include full text content from source pages
|
|
382
|
-
- `--output-format FORMAT` - json or pretty (default: json)
|
|
383
|
-
- `--api-key KEY` - API key (or set EXA_API_KEY env var)
|
|
384
|
-
|
|
385
|
-
**Response fields:**
|
|
386
|
-
- `answer` - The generated answer to your question
|
|
387
|
-
- `citations` - Array of source citations with URLs
|
|
388
|
-
- `cost_dollars` - Cost of the API request
|
|
389
|
-
|
|
390
|
-
### Context Command (Code Search)
|
|
391
|
-
|
|
392
|
-
Find code snippets and context from open-source repositories:
|
|
393
|
-
|
|
394
|
-
```bash
|
|
395
|
-
# Basic query
|
|
396
|
-
exa-ai context "authentication with JWT"
|
|
397
|
-
|
|
398
|
-
# With custom token allocation
|
|
91
|
+
# Core Search Commands
|
|
92
|
+
exa-ai search "Ruby programming language"
|
|
93
|
+
exa-ai find-similar "https://arxiv.org/abs/2307.06435"
|
|
94
|
+
exa-ai answer "What is machine learning?"
|
|
399
95
|
exa-ai context "React hooks" --tokens-num 5000
|
|
96
|
+
exa-ai get-contents "https://ruby-lang.org"
|
|
400
97
|
|
|
401
|
-
#
|
|
402
|
-
exa-ai
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
**Options:**
|
|
406
|
-
- `QUERY` - Search query (required)
|
|
407
|
-
- `--tokens-num NUM` - Token allocation, integer or "dynamic" (default: dynamic)
|
|
408
|
-
- `--output-format FORMAT` - json or text (default: json)
|
|
409
|
-
- `--api-key KEY` - API key
|
|
410
|
-
|
|
411
|
-
### Get-Contents Command
|
|
412
|
-
|
|
413
|
-
Retrieve the full text content from web pages:
|
|
414
|
-
|
|
415
|
-
```bash
|
|
416
|
-
# Single page
|
|
417
|
-
exa-ai get-contents "https://example.com/article"
|
|
418
|
-
|
|
419
|
-
# Multiple pages (comma-separated)
|
|
420
|
-
exa-ai get-contents "https://site1.com,https://site2.com"
|
|
421
|
-
|
|
422
|
-
# With options
|
|
423
|
-
exa-ai get-contents "id1,id2,id3" \
|
|
424
|
-
--text \
|
|
425
|
-
--highlights \
|
|
426
|
-
--output-format pretty
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
**Options:**
|
|
430
|
-
- `IDS` - Page IDs or URLs (required, comma-separated)
|
|
431
|
-
- `--text` - Include full text content
|
|
432
|
-
- `--highlights` - Include highlighted sections
|
|
433
|
-
- `--summary` - Include summary
|
|
434
|
-
- `--output-format FORMAT` - json or pretty (default: json)
|
|
435
|
-
- `--api-key KEY` - API key
|
|
436
|
-
|
|
437
|
-
### Research Commands
|
|
438
|
-
|
|
439
|
-
Start and manage long-running research tasks:
|
|
440
|
-
|
|
441
|
-
#### research-start
|
|
442
|
-
|
|
443
|
-
```bash
|
|
444
|
-
# Start a task
|
|
445
|
-
exa-ai research-start --instructions "Find Ruby performance tips"
|
|
446
|
-
|
|
447
|
-
# Start and wait for completion
|
|
448
|
-
exa-ai research-start \
|
|
449
|
-
--instructions "Analyze AI safety papers" \
|
|
450
|
-
--model gpt-4 \
|
|
451
|
-
--wait
|
|
452
|
-
|
|
453
|
-
# With output schema
|
|
454
|
-
exa-ai research-start \
|
|
455
|
-
--instructions "Extract key metrics" \
|
|
456
|
-
--output-schema '{"format":"json","fields":["metric","value"]}'
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
**Options:**
|
|
460
|
-
- `--instructions TEXT` - Research instructions (required)
|
|
461
|
-
- `--model MODEL` - Model to use (e.g., gpt-4)
|
|
462
|
-
- `--output-schema SCHEMA` - JSON schema for structured output
|
|
463
|
-
- `--wait` - Wait for task to complete (with polling)
|
|
464
|
-
- `--events` - Show event log during polling
|
|
465
|
-
- `--output-format FORMAT` - json or pretty (default: json)
|
|
466
|
-
- `--api-key KEY` - API key
|
|
467
|
-
|
|
468
|
-
#### research-get
|
|
469
|
-
|
|
470
|
-
```bash
|
|
471
|
-
# Check task status
|
|
472
|
-
exa-ai research-get abc-123
|
|
473
|
-
|
|
474
|
-
# With events
|
|
475
|
-
exa-ai research-get abc-123 --events
|
|
476
|
-
|
|
477
|
-
# Pretty output
|
|
478
|
-
exa-ai research-get abc-123 --output-format pretty
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
**Options:**
|
|
482
|
-
- `RESEARCH_ID` - Task ID (required)
|
|
483
|
-
- `--events` - Include event log
|
|
484
|
-
- `--stream` - Stream results (premium feature)
|
|
485
|
-
- `--output-format FORMAT` - json or pretty (default: json)
|
|
486
|
-
- `--api-key KEY` - API key
|
|
487
|
-
|
|
488
|
-
#### research-list
|
|
489
|
-
|
|
490
|
-
```bash
|
|
491
|
-
# List all tasks
|
|
98
|
+
# Research Commands
|
|
99
|
+
exa-ai research-start --instructions "What species of ant are similar to honeypot ants?"
|
|
100
|
+
exa-ai research-get RESEARCH_ID
|
|
492
101
|
exa-ai research-list
|
|
493
102
|
|
|
494
|
-
#
|
|
495
|
-
exa-ai
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
exa-ai
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
-
|
|
506
|
-
-
|
|
507
|
-
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
**
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
103
|
+
# Webset Management
|
|
104
|
+
exa-ai webset-create --search '{"query":"technology companies","count":1}'
|
|
105
|
+
exa-ai webset-list --limit 5
|
|
106
|
+
exa-ai webset-get WEBSET_ID
|
|
107
|
+
exa-ai webset-update WEBSET_ID --metadata '{"updated":"true","version":"2"}'
|
|
108
|
+
exa-ai webset-delete WEBSET_ID --force
|
|
109
|
+
exa-ai webset-cancel WEBSET_ID
|
|
110
|
+
|
|
111
|
+
# Webset Searches
|
|
112
|
+
exa-ai webset-search-create WEBSET_ID --query "Ford Mustang" --entity custom --entity-description "vintage cars"
|
|
113
|
+
exa-ai webset-search-create WEBSET_ID --query "tech CEOs" --entity person --count 20
|
|
114
|
+
exa-ai webset-search-create WEBSET_ID --query "Y Combinator startups" --entity company
|
|
115
|
+
exa-ai webset-search-get WEBSET_ID SEARCH_ID
|
|
116
|
+
exa-ai webset-search-cancel WEBSET_ID SEARCH_ID
|
|
117
|
+
|
|
118
|
+
# Webset Items
|
|
119
|
+
exa-ai webset-item-list WEBSET_ID
|
|
120
|
+
exa-ai webset-item-get WEBSET_ID ITEM_ID
|
|
121
|
+
exa-ai webset-item-delete WEBSET_ID ITEM_ID --force
|
|
122
|
+
|
|
123
|
+
# Enrichments
|
|
124
|
+
exa-ai enrichment-create WEBSET_ID --description "Find company email" --format text
|
|
125
|
+
exa-ai enrichment-create WEBSET_ID --description "Company size category" --format options --options '[{"label":"Small (1-10)"},{"label":"Medium (11-50)"},{"label":"Large (51+)"}]'
|
|
126
|
+
exa-ai enrichment-list WEBSET_ID
|
|
127
|
+
exa-ai enrichment-get WEBSET_ID ENRICHMENT_ID
|
|
128
|
+
exa-ai enrichment-update WEBSET_ID ENRICHMENT_ID --description "Updated description"
|
|
129
|
+
exa-ai enrichment-delete WEBSET_ID ENRICHMENT_ID --force
|
|
130
|
+
exa-ai enrichment-cancel WEBSET_ID ENRICHMENT_ID
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Features
|
|
134
|
+
|
|
135
|
+
The gem provides complete access to Exa's API endpoints:
|
|
136
|
+
|
|
137
|
+
### Core Search
|
|
138
|
+
- **Search** — Neural and keyword search across billions of web pages
|
|
139
|
+
- **Find Similar** — Discover content similar to a given URL
|
|
140
|
+
- **Answer** — Generate comprehensive answers with source citations
|
|
141
|
+
- **Context** — Find relevant code and documentation snippets
|
|
142
|
+
- **Get Contents** — Extract full text content from web pages
|
|
143
|
+
|
|
144
|
+
### Research
|
|
145
|
+
- **Research Tasks** — Start and manage long-running research tasks with AI
|
|
146
|
+
- **Task Management** — Get status updates and list all research tasks
|
|
147
|
+
|
|
148
|
+
### Websets
|
|
149
|
+
- **Webset Management** — Create, update, delete, and list datasets of web pages
|
|
150
|
+
- **Webset Searches** — Run searches within websets and manage search tasks
|
|
151
|
+
- **Webset Items** — List, retrieve, and manage individual items in websets
|
|
152
|
+
- **Enrichments** — Create and manage AI-powered data enrichment tasks on websets
|
|
538
153
|
|
|
539
154
|
## Error Handling
|
|
540
155
|
|
|
541
|
-
The CLI provides helpful error messages:
|
|
542
|
-
|
|
543
|
-
```bash
|
|
544
|
-
# Missing API key
|
|
545
|
-
$ exa search "test"
|
|
546
|
-
❌ Configuration Error
|
|
547
|
-
|
|
548
|
-
Missing API key. Set EXA_API_KEY or use --api-key
|
|
549
|
-
|
|
550
|
-
Solutions:
|
|
551
|
-
1. Set the EXA_API_KEY environment variable:
|
|
552
|
-
export EXA_API_KEY='your-api-key'
|
|
553
|
-
...
|
|
554
|
-
|
|
555
|
-
# Invalid credentials
|
|
556
|
-
$ exa search "test" --api-key bad-key
|
|
557
|
-
❌ Authentication Error
|
|
558
|
-
|
|
559
|
-
Your API key is invalid or has expired.
|
|
560
|
-
...
|
|
561
|
-
|
|
562
|
-
# Rate limited
|
|
563
|
-
$ exa search "test" # After many requests
|
|
564
|
-
❌ Request Error
|
|
565
|
-
|
|
566
|
-
You've exceeded the rate limit. Please wait before trying again.
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
### Ruby API Error Handling
|
|
570
|
-
|
|
571
156
|
```ruby
|
|
572
|
-
|
|
157
|
+
require 'exa-ai'
|
|
158
|
+
|
|
159
|
+
client = Exa::Client.new(api_key: "your-key")
|
|
573
160
|
|
|
574
161
|
begin
|
|
575
162
|
results = client.search("test")
|
|
576
163
|
rescue Exa::Unauthorized => e
|
|
577
164
|
puts "Invalid API key: #{e.message}"
|
|
578
165
|
rescue Exa::TooManyRequests => e
|
|
579
|
-
puts "Rate limited, please
|
|
166
|
+
puts "Rate limited, please retry"
|
|
580
167
|
rescue Exa::ServerError => e
|
|
581
|
-
puts "
|
|
168
|
+
puts "Server error: #{e.message}"
|
|
582
169
|
end
|
|
583
170
|
```
|
|
584
171
|
|
|
585
|
-
##
|
|
586
|
-
|
|
587
|
-
### CLI Examples
|
|
588
|
-
|
|
589
|
-
```bash
|
|
590
|
-
# Find Ruby tutorials
|
|
591
|
-
exa search "Ruby best practices" --num-results 5
|
|
592
|
-
|
|
593
|
-
# Get an answer to a question
|
|
594
|
-
exa answer "What is machine learning?"
|
|
595
|
-
|
|
596
|
-
# Get code examples for async/await
|
|
597
|
-
exa context "async/await error handling"
|
|
598
|
-
|
|
599
|
-
# Research AI trends
|
|
600
|
-
exa research-start --instructions "What are latest AI trends?" --wait
|
|
601
|
-
|
|
602
|
-
# Retrieve and analyze multiple pages
|
|
603
|
-
exa get-contents "url1,url2,url3" --text --output-format pretty
|
|
604
|
-
```
|
|
605
|
-
|
|
606
|
-
### Ruby API Examples
|
|
607
|
-
|
|
608
|
-
```ruby
|
|
609
|
-
require 'exa'
|
|
610
|
-
|
|
611
|
-
Exa.configure do |config|
|
|
612
|
-
config.api_key = ENV['EXA_API_KEY']
|
|
613
|
-
end
|
|
614
|
-
|
|
615
|
-
client = Exa::Client.new
|
|
616
|
-
|
|
617
|
-
# Search with filtering
|
|
618
|
-
results = client.search("kubernetes tutorial",
|
|
619
|
-
num_results: 20,
|
|
620
|
-
type: "neural",
|
|
621
|
-
include_domains: ["kubernetes.io", "github.com"]
|
|
622
|
-
)
|
|
623
|
-
|
|
624
|
-
results.results.each do |item|
|
|
625
|
-
puts "#{item['title']} (#{item['url']})"
|
|
626
|
-
end
|
|
172
|
+
## Documentation
|
|
627
173
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
# Start async research
|
|
633
|
-
task = client.research_start(
|
|
634
|
-
instructions: "Summarize recent ML papers",
|
|
635
|
-
model: "gpt-4"
|
|
636
|
-
)
|
|
637
|
-
puts "Task started: #{task.research_id}"
|
|
638
|
-
|
|
639
|
-
# Poll for results
|
|
640
|
-
loop do
|
|
641
|
-
status = client.research_get(task.research_id)
|
|
642
|
-
break if status.completed? || status.failed?
|
|
643
|
-
sleep 5
|
|
644
|
-
end
|
|
645
|
-
|
|
646
|
-
if status.completed?
|
|
647
|
-
puts status.output
|
|
648
|
-
end
|
|
649
|
-
```
|
|
174
|
+
- **[Full Ruby API Documentation](./docs/API.md)** — All methods and parameters
|
|
175
|
+
- **[CLI Command Reference](./docs/CLI.md)** — All CLI commands and options
|
|
176
|
+
- **[Exa API Docs](https://docs.exa.ai)** — Exa API reference
|
|
650
177
|
|
|
651
178
|
## Development
|
|
652
179
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
# Run specific test file
|
|
660
|
-
bundle exec ruby test/cli/search_test.rb
|
|
661
|
-
|
|
662
|
-
# Run with verbose output
|
|
663
|
-
bundle exec rake test TESTOPTS="-v"
|
|
664
|
-
```
|
|
665
|
-
|
|
666
|
-
### Building the Gem
|
|
667
|
-
|
|
668
|
-
```bash
|
|
669
|
-
bundle exec rake build
|
|
670
|
-
bundle exec rake install
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
## Documentation
|
|
674
|
-
|
|
675
|
-
- [Exa API Documentation](https://docs.exa.ai)
|
|
676
|
-
- [API Reference](https://docs.exa.ai/reference)
|
|
677
|
-
- [Status Page](https://status.exa.ai)
|
|
180
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for:
|
|
181
|
+
- Running tests
|
|
182
|
+
- Development setup
|
|
183
|
+
- Code conventions
|
|
184
|
+
- Building and releasing
|
|
678
185
|
|
|
679
186
|
## Support
|
|
680
187
|
|
|
681
188
|
- **Documentation**: https://docs.exa.ai
|
|
682
|
-
- **
|
|
189
|
+
- **Dashboard**: https://dashboard.exa.ai
|
|
683
190
|
- **Status**: https://status.exa.ai
|
|
684
191
|
|
|
685
192
|
## License
|
|
686
193
|
|
|
687
|
-
MIT License - See LICENSE file for details
|
|
688
|
-
|
|
689
|
-
## Changelog
|
|
690
|
-
|
|
691
|
-
See [CHANGELOG.md](CHANGELOG.md) for version history and updates.
|
|
194
|
+
MIT License - See [LICENSE](LICENSE) file for details
|
|
692
195
|
|
|
693
196
|
---
|
|
694
197
|
|
|
695
|
-
**Built with Exa.ai**
|
|
198
|
+
**Built with [Exa.ai](https://exa.ai)** — The search and discovery API
|