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
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # exa-ruby
2
2
 
3
- Ruby client for the Exa.ai API with comprehensive command-line interface.
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
- **Option 1: Environment Variable (recommended)**
29
+ **Environment Variable (recommended)**
34
30
 
35
31
  ```bash
36
32
  export EXA_API_KEY="your-api-key-here"
37
33
  ```
38
34
 
39
- **Option 2: Ruby Code**
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
- **Option 3: CLI Flag**
48
+ **CLI Flag**
53
49
 
54
50
  ```bash
55
51
  exa-ai search "query" --api-key YOUR_API_KEY
56
52
  ```
57
53
 
58
- ## Ruby API Usage
54
+ ## Quick Start
59
55
 
60
- ### Quick Start
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("ruby programming")
73
- puts results.results.first["title"]
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 are the latest trends in AI?")
76
+ answer = client.answer("What is machine learning?")
77
77
  puts answer.answer
78
- puts answer.citations
79
78
 
80
- # Get code context
79
+ # Find code examples
81
80
  code = client.context("React hooks")
82
81
  puts code.response
83
82
 
84
- # Retrieve page contents
85
- contents = client.get_contents(["https://example.com"])
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
- ### Search
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
- exa-ai <command> [options]
186
-
187
- Commands:
188
- search Search the web
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
- # Text output
402
- exa-ai context "async/await patterns" --output-format text
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
- # With pagination
495
- exa-ai research-list --limit 20
496
-
497
- # Next page
498
- exa-ai research-list --cursor "next_page_cursor"
499
-
500
- # Pretty table format
501
- exa-ai research-list --output-format pretty
502
- ```
503
-
504
- **Options:**
505
- - `--cursor CURSOR` - Pagination cursor
506
- - `--limit N` - Results per page (default: 10)
507
- - `--output-format FORMAT` - json or pretty (default: json)
508
- - `--api-key KEY` - API key
509
-
510
- ### Global Options
511
-
512
- All commands support:
513
- - `--api-key KEY` - Override API key
514
- - `--output-format FORMAT` - json, pretty, or text (varies by command)
515
- - `--help, -h` - Show command help
516
- - `exa-ai --version` - Show version
517
- - `exa-ai --help` - Show available commands
518
-
519
- ### Output Formats
520
-
521
- **JSON (default)**
522
- ```bash
523
- exa-ai search "ruby" --output-format json
524
- # Returns formatted JSON object
525
- ```
526
-
527
- **Pretty**
528
- ```bash
529
- exa-ai search "ruby" --output-format pretty
530
- # Returns human-readable format with titles, URLs, scores
531
- ```
532
-
533
- **Text**
534
- ```bash
535
- exa-ai context "React" --output-format text
536
- # Returns plain text output
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
- client = Exa::Client.new(api_key: "test")
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 wait"
166
+ puts "Rate limited, please retry"
580
167
  rescue Exa::ServerError => e
581
- puts "API error: #{e.message}"
168
+ puts "Server error: #{e.message}"
582
169
  end
583
170
  ```
584
171
 
585
- ## Examples
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
- # Get code context
629
- code_result = client.context("Docker best practices", tokens_num: 5000)
630
- puts code_result.response
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
- ### Running Tests
654
-
655
- ```bash
656
- # Run all tests
657
- bundle exec rake test
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
- - **API Key**: https://dashboard.exa.ai
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** - Search and discovery API for the web
198
+ **Built with [Exa.ai](https://exa.ai)** The search and discovery API