Project

exa-rb

0.0
No release in over 3 years
The Exa gem implements a lightweight interface to the Exa.ai API. Exa provides powerful neural search capabilities that go beyond traditional keyword matching to understand semantic meaning and context. This gem supports search, find similar, answer, and contents endpoints. It includes both a Ruby API and a command-line interface (exa) for quick searches from the terminal.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 1.9
~> 5.25
~> 6.3

Runtime

 Project Readme

Exa

The Exa gem provides a Ruby interface to the Exa API, enabling powerful neural and keyword-based web search with content retrieval capabilities. Exa goes beyond traditional keyword matching to understand semantic meaning and context, making it particularly useful for applications that need intelligent search, including those using Large Language Models.

require 'exa'

Exa.api_key ENV[ 'EXA_API_KEY' ]

response = Exa.search( 'best practices for Ruby API design' )
if response.success?
  response.result.each do | result |
    puts result.title
    puts result.url
  end
end

Table of Contents

  • Installation
  • Command Line
  • Quick Start
  • Endpoints
    • Search
    • Find Similar
    • Answer
    • Contents
  • Responses and Errors
  • Connections
  • License

Installation

Add this line to your application's Gemfile:

gem 'exa-rb'

Then execute:

bundle install

Or install it directly:

gem install exa-rb

Command Line

The gem includes an exa command for quick searches from the terminal:

exa search "Ruby programming best practices"
exa answer "What is the Ruby programming language?"
exa similar https://www.ruby-lang.org/en/

Set your API key via environment variable:

export EXA_API_KEY=your_api_key

Quick Start

The simplest way to use the gem is through the module-level convenience methods. Set your API key once, then call any endpoint:

require 'exa'

Exa.api_key ENV[ 'EXA_API_KEY' ]

response = Exa.search( 'machine learning tutorials' )
if response.success?
  response.result.each do | result |
    puts result.title
    puts result.url
  end
end

For more control, instantiate request objects directly. This allows you to configure options using a block-based DSL and reuse request instances:

request = Exa::SearchRequest.new( api_key: ENV[ 'EXA_API_KEY' ] )

options = Exa::SearchOptions.build do
  num_results 10
  type :neural
  contents do
    text { max_characters 1000 }
    highlights { num_sentences 2 }
  end
end

response = request.submit( 'Ruby web frameworks', options )

Endpoints

Search

The search endpoint performs web searches using neural or keyword-based methods and returns relevant results with optional content retrieval.

options = Exa::SearchOptions.build do
  num_results 5
  type :neural
  include_domains [ 'github.com', 'stackoverflow.com' ]
  contents do
    summary { query 'Summarize the key points' }
  end
end

response = Exa.search( 'Ruby dependency injection patterns', options )

if response.success?
  response.result.each do | result |
    puts result.title
    puts result.url
    puts result.summary
  end
end

For complete documentation of all search options and response fields, see Search Documentation.

Find Similar

The find similar endpoint finds pages that are similar to a given URL:

options = Exa::FindSimilarOptions.build do
  num_results 5
  exclude_source_domain true
  contents do
    summary { query 'Summarize the content' }
  end
end

response = Exa.find_similar( 'https://www.ruby-lang.org/en/', options )

if response.success?
  response.result.each do | result |
    puts result.title
    puts result.url
    puts result.summary
  end
end

For complete documentation of all find similar options and response fields, see Find Similar Documentation.

Answer

The answer endpoint provides AI-generated answers to questions using web sources:

response = Exa.answer( 'What is the Ruby programming language?' )

if response.success?
  puts response.result.answer

  puts "\nCitations:"
  response.result.citations.each do | citation |
    puts "- #{ citation.title }: #{ citation.url }"
  end
end

To include full text from citations:

options = Exa::AnswerOptions.build do
  text true
end

response = Exa.answer( 'How does garbage collection work in Ruby?', options )

For complete documentation of all answer options and response fields, see Answer Documentation.

Contents

The contents endpoint retrieves full page content, summaries, and highlights for a list of URLs:

urls = [
  'https://ruby-doc.org/core/Array.html',
  'https://ruby-doc.org/core/Hash.html'
]

options = Exa::ContentsOptions.build do
  text { max_characters 2000 }
  highlights do
    num_sentences 3
    highlights_per_url 5
  end
end

response = Exa.contents( urls, options )

if response.success?
  response.result.each do | result |
    puts result.title
    puts result.text
  end
end

For complete documentation of all contents options and response fields, see Contents Documentation.


Responses and Errors

All request methods return a Faraday::Response object. Check response.success? to determine if the HTTP request succeeded. When successful, response.result contains the parsed result object specific to the endpoint.

response = Exa.search( query, options )

if response.success?
  result = response.result
  result.each do | item |
    puts item.title
  end
else
  error = response.result
  puts error.error_type         # :authentication_error, :rate_limit_error, etc.
  puts error.error_description  # human-readable message
end

The gem maps HTTP status codes to error types:

Status Error Type Description
400 :invalid_request_error Invalid request parameters or malformed JSON
401 :authentication_error Missing or invalid API key
403 :forbidden_error Insufficient permissions or rate limit exceeded
404 :not_found_error The requested resource was not found
409 :conflict_error Resource already exists
429 :rate_limit_error Rate limit exceeded
500-599 :server_error A server error occurred

Connections

The gem uses Faraday for HTTP requests, which means you can customize the connection configuration. To use a custom connection:

connection = Faraday.new do | faraday |
  faraday.request :json
  faraday.response :logger
  faraday.adapter :net_http
end

Exa.connection connection

Or pass it directly to a request:

request = Exa::SearchRequest.new(
  api_key: ENV[ 'EXA_API_KEY' ],
  connection: connection
)

License

The gem is available as open source under the terms of the MIT License.