Skip to content

Feat/web-search perplexity exa#1350

Merged
esengine merged 2 commits into
esengine:mainfrom
dacec354:feat/web-perplexity-exa
May 20, 2026
Merged

Feat/web-search perplexity exa#1350
esengine merged 2 commits into
esengine:mainfrom
dacec354:feat/web-perplexity-exa

Conversation

@dacec354

Copy link
Copy Markdown

What

Add Perplexity and Exa as new web_search backends alongside existing mojeek/searxng/metaso/tavily, with inline API key configuration via /search-engine <name> <key>.

Why

Perplexity and Exa are "AI-native" search providers — they return a direct synthesis answer with citations rather than just a link list. This gives the model an answer: section (prepended before the source list) that it can use directly, skipping the need to synthesize results itself.

Perplexity: api.perplexity.ai/chat/completions — model sonar
Exa: api.exa.ai/answer — free 1000 req/mo

Tavily was already implemented; this PR rounds out the AI-native tier.

What changed

File Change
src/config.ts perplexityApiKey / exaApiKey config fields + loadPerplexityApiKey() / loadExaApiKey()
src/tools/web.ts searchPerplexity() / searchExa() functions; webSearchOptions.engine union extended; formatSearchResults() detects AI answer and outputs answer: + sources: dual-section format
src/i18n/EN.ts Perplexity/Exa error messages with healing hints; slash description updated
src/i18n/zh-CN.ts Same in Chinese
src/i18n/types.ts Type declarations for new error keys
src/index.ts Export new config loaders
src/cli/ui/slash/commands.ts argCompleter, argsHint, summary include all 6 engines
src/cli/ui/slash/handlers/web-search-engine.ts Inline key save (/search-engine <name> <key>); rejects switch when key missing with guidance; no duplicate messages

UX

/search-engine perplexity                  # no key → guidance with env var name
/search-engine perplexity pplx-xxxxx        # saves key + switches
/search-engine perplexity                   # key exists → clean switch, no config hint

How to verify

  1. tsc --noEmit passes
  2. Set PERPLEXITY_API_KEY or EXA_API_KEY
  3. Run the CLI, type /search-engine perplexity — should switch cleanly
  4. Type /search-engine exa — same
  5. Without a key, /search-engine exa should show the numbered guidance instead of switching
  6. /search-engine tab completion shows all 6 engines

Checklist

  • npm run verify passes locally (lint + typecheck + tests + comment-policy gate)
  • No Co-Authored-By: Claude trailer in commits
  • Comments follow CONTRIBUTING.md (no module-essay headers, no incident history)
  • No edits to CHANGELOG.md — release notes are maintainer-written at release time

@dacec354 dacec354 changed the title Feat/web perplexity exa Feat/web-search perplexity exa May 19, 2026
Comment thread src/tools/web.ts
Comment on lines +354 to +357
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
Comment thread src/tools/web.ts
Comment on lines +443 to +446
headers: {
"x-api-key": apiKey,
"Content-Type": "application/json",
},
@dacec354 dacec354 force-pushed the feat/web-perplexity-exa branch 2 times, most recently from f6a19b7 to 5f14995 Compare May 19, 2026 16:48
@esengine esengine merged commit db3a0d0 into esengine:main May 20, 2026
7 checks passed
@esengine

Copy link
Copy Markdown
Owner

Thanks @dacec354 — clean additive shape, default mojeek untouched, i18n EN+zh-CN complete, error mapping consistent with the tavily pattern. The /search-engine <name> <key> inline-save UX is a nice touch.

Two follow-ups I'll handle silently:

  1. The new // ── Perplexity ── / // ── Exa ── / // ── API-key engines ── section-banner separators are on the CLAUDE.md ban list; they'll go away in a cleanup pass.
  2. tavily has full unit coverage in tests/web-tools.test.ts (missing-key, unauthorized, rate-limit, parse-error, body shape). Perplexity and Exa need the same coverage so a future fetch-shape change can't regress them silently — I'll add those in a follow-up.

Nothing for you to fix on this PR. Looking forward to more.

esengine added a commit that referenced this pull request May 20, 2026
…ents (#1366)

Two follow-ups to #1350:

1. Perplexity / Exa landed without unit tests, while tavily has 5
   covering missing-key / 401 / 429 / parse-error / body shape. Mirror
   that pattern so a fetch-shape change in either backend can't regress
   silently. Also add a formatSearchResults case for the new "answer +
   sources" dual-section branch.

2. Drop the `// ── Perplexity ──` / `// ── Exa ──` / `// ── API-key
   engines ──` section-banner separators — CLAUDE.md bans them; group
   by export instead.

Co-authored-by: reasonix <reasonix@deepseek.com>
ChasLui pushed a commit to ChasLui/DeepSeek-Reasonix that referenced this pull request May 23, 2026
* feat: add Perplexity and Exa as web_search engines

* fix: biome lint errors and update public API snapshot
ChasLui pushed a commit to ChasLui/DeepSeek-Reasonix that referenced this pull request May 23, 2026
…ents (esengine#1366)

Two follow-ups to esengine#1350:

1. Perplexity / Exa landed without unit tests, while tavily has 5
   covering missing-key / 401 / 429 / parse-error / body shape. Mirror
   that pattern so a fetch-shape change in either backend can't regress
   silently. Also add a formatSearchResults case for the new "answer +
   sources" dual-section branch.

2. Drop the `// ── Perplexity ──` / `// ── Exa ──` / `// ── API-key
   engines ──` section-banner separators — CLAUDE.md bans them; group
   by export instead.

Co-authored-by: reasonix <reasonix@deepseek.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants