#777
feat: add Exa AI-powered search tool
Summary
Adds an exa_search tool so the agent can do AI-powered web search alongside the existing web_fetch (which only fetches a known URL). Useful for looking up library docs the model doesn't know, finding code examples on GitHub, or researching error messages without first having to guess the right URL.
- New tool at
packages/agent/tools/exa-search.ts, registered asexa_searchinopen-harness-agent.ts - Direct call to
https://api.exa.ai/searchviafetch(no SDK dependency added) - Reads
EXA_API_KEYfrom env; returns a structured error when unset so the agent can fall back gracefully - Exposes the most useful Exa knobs:
type(auto/neural/fast/instant),category(incl.githubfor code search),numResults,includeDomains/excludeDomains,includeText/excludeText, and date-range filters - Each result returns
title,url, optionalpublishedDate/author, and asnippetthat cascades through highlights → summary → text depending on what the API returns - System-prompt updated with a short
Websection so the model knows when to preferexa_searchoverweb_fetch
Example usage
// Look up library docs
exa_search({ query: "drizzle-orm migrations cli usage", numResults: 5 })
// Find a code example on GitHub
exa_search({
query: "next.js streaming server component example",
category: "github",
})
// Debug an error, scoped to Stack Overflow
exa_search({
query: "TypeError Cannot read properties of undefined reading 'map' react",
includeDomains: ["stackoverflow.com"],
})Files changed
packages/agent/tools/exa-search.ts— new toolpackages/agent/tools/exa-search.test.ts— 14 unit testspackages/agent/tools/index.ts— exportpackages/agent/open-harness-agent.ts— register asexa_searchpackages/agent/system-prompt.ts— add aWebsection listing both toolsapps/web/.env.example— documentEXA_API_KEY
Test plan
-
bun run --filter @open-harness/agent typecheck— passes -
bun run typecheck(all packages) — passes -
bun run check(ultracite lint + format) — passes -
bun test packages/agent/tools/— 37/37 pass (14 new + 23 existing) - Tests cover: request body shape with/without optional filters; snippet fallback through highlights → summary → text; empty-content case;
EXA_API_KEYunset error path; auth +x-exa-integrationheaders; non-2xx and thrown-error paths - End-to-end with a live API key — not run in CI; requires
EXA_API_KEY
@tgonzalezc5 is attempting to deploy a commit to the Vercel Labs Team on Vercel.
A member of the Team first needs to authorize it.