Skip to main content

Tavily Search Plugin

The Tavily plugin provides AI-optimized web search and content extraction through the Tavily API. It is the default search provider in Ever Works and powers source discovery during work generation.

Source: packages/plugins/tavily/src/tavily.plugin.ts

Overview

PropertyValue
Plugin IDtavily
Categorysearch
Capabilitiessearch, content-extractor
Version1.0.0
Configuration Modehybrid
Auto-enableYes
System pluginYes
Default forsearch capability
SDK@tavily/core

The plugin implements three interfaces: IPlugin, ISearchPlugin, and IContentExtractorPlugin. It is a system plugin that is auto-enabled and serves as the default search provider.

Architecture

Dual Capability

Unlike single-purpose plugins, Tavily handles both search and content extraction:

CapabilityMethodDescription
searchsearch(options)Find web pages relevant to a query
content-extractorextract(options)Pull clean text content from a URL

During work generation, the pipeline uses the search capability to discover sources and the content extraction capability to pull full text from those sources.

Configuration

Settings Schema

SettingTypeRequiredScopeDescription
apiKeystringYesuserTavily API key (marked as secret)

The API key is mapped to the environment variable PLUGIN_TAVILY_API_KEY via the x-envVar schema extension:

{
"apiKey": {
"type": "string",
"title": "API Key",
"description": "Your Tavily API key. Get one at https://tavily.com",
"x-secret": true,
"x-envVar": "PLUGIN_TAVILY_API_KEY",
"x-scope": "user"
}
}

Configuration Mode: Hybrid

The hybrid configuration mode means:

  • Admin level: The platform administrator can set a shared API key that all users inherit.
  • User level: Individual users can provide their own API key, which takes precedence over the admin key.
  • Environment variable: As a final fallback, the key is read from PLUGIN_TAVILY_API_KEY in the API .env file.

Method Signature

async search(options: SearchOptions): Promise<SearchResponse>

Search Options

OptionTypeDefaultDescription
querystring(required)The search query
limitnumber20Maximum number of results to return
includeDomainsstring[](empty)Only include results from these domains
excludeDomainsstring[](empty)Exclude results from these domains
settingsPluginSettings(resolved)Plugin settings including the API key

Search Behavior

The plugin uses searchDepth: 'advanced' for all queries, which performs a more thorough search at the cost of slightly slower results. The response is transformed into the standard SearchResponse format:

const response = await client.search(options.query, {
searchDepth: 'advanced',
maxResults,
includeDomains: options.includeDomains,
excludeDomains: options.excludeDomains
});

Search Result Fields

Each result in the SearchResponse contains:

FieldSourceDescription
titleTavily titlePage title
urlTavily urlPage URL
snippetTavily contentExtracted text snippet
positionIndex + 1Result ranking position
publishedDateTavily publishedDatePublication date if available
metadata.scoreTavily scoreRelevance score
metadata.rawContentTavily rawContentFull extracted content

Content Extraction

Single URL Extraction

async extract(options: ContentExtractionOptions): Promise<ContentExtractionResult>

Extracts clean text content from a single URL using the Tavily extract API:

const response = await client.extract([options.url]);

The result includes:

FieldDescription
successWhether extraction succeeded
urlThe requested URL
finalUrlThe resolved URL if it differs from the request
contentExtracted text content
markdownContent in markdown format
wordCountNumber of words extracted
durationTime taken in milliseconds

Batch Extraction

async extractBatch(
urls: readonly string[],
options?: Partial<ContentExtractionOptions>
): Promise<readonly ContentExtractionResult[]>

Extracts content from multiple URLs in a single API call. All URLs are sent to Tavily together and results are mapped back to the original URL order. If the batch call fails, all results are returned with success: false.

URL Support

The canExtract() method accepts any http: or https: URL:

async canExtract(url: string): Promise<boolean> {
const parsed = new URL(url);
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
}

Supported output formats: text, markdown.

Error Handling

Both search and extraction methods wrap their logic in try/catch blocks. Search errors are logged and re-thrown (so the pipeline can handle them), while extraction errors are returned as failed results with error details:

// Search: re-throws
catch (error) {
this.context?.logger.error(`Tavily failed: ${error.message}`);
throw error;
}

// Extract: returns failure
catch (error) {
return {
success: false,
url: options.url,
error: error.message,
duration: Date.now() - startTime
};
}

How Tavily Is Used in the Pipeline

During work generation, Tavily participates in two stages:

  1. Source Discovery -- The search facade calls search() with queries derived from the work prompt and subject to find relevant web pages.
  2. Content Extraction -- The content extraction facade calls extract() on discovered URLs to pull full text that the AI uses to generate item descriptions.

Getting Started

  1. Create an account at tavily.com.
  2. Copy your API key from the Tavily dashboard.
  3. Enter the key in the plugin settings or set the PLUGIN_TAVILY_API_KEY environment variable.
  4. Tavily is auto-enabled and will be used automatically during work generation.

Troubleshooting

IssueCauseSolution
"Tavily API key not configured"No API key at any settings levelSet the key in plugin settings or .env
Search returns empty resultsQuery too specific or domain filters too strictBroaden the query or remove domain filters
Extraction returns no contentPage blocks automated accessTry a different content extractor plugin
Rate limit errorsToo many API callsCheck your Tavily plan limits and reduce batch sizes