microsoft / microsoft/vscode-websearchforcopilot

Support pluggable search engines — add Perplexity (direct or via LiteLLM-style proxy)

Open
#85 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
65
Forks
15
PR merge metrics
No merged PRs in 30d

Description

Summary

The extension currently hard-codes Tavily as the only web search backend. It would be great to support pluggable search engines — in particular Perplexity's Search API, which has a compatible results shape and is also available through OpenAI-compatible proxies (e.g. LiteLLM gateway at an https://<host>/v1/search/perplexity-search route).

Motivation

Corporate/offline-adjacent setups often already have a fronting gateway for LLM traffic (LiteLLM-style proxies exposing inference-api endpoints) that also proxies Perplexity search. Users in those environments cannot sign up for Tavily and thus the vscode-websearchforcopilot_webSearch LM tool and the @websearch participant are unusable today — TavilyEngine.search() calls vscode.authentication.getSession('tavily', ..., { createIfNone: true }), which blocks on a key they'll never have.

Current coupling points

  • src/search/webSearch.tsTavilyEngine with static search() / extract() methods; API key passed in the POST body (api_key), which is Tavily-specific auth.
  • src/search/webSearchTypes.ts — request/response types reference Tavily schemas.
  • src/chatTool.tsx — calls TavilyEngine.search() directly.

Proposed shape (happy to send a PR)

  1. Introduce an ISearchEngine interface in webSearchTypes.ts:
    interface ISearchEngine {
      search(query: string, opts?: { maxResults?: number; domains?: string[]; recency?: string }): Promise<IWebSearchResults>;
      extract?(urls: string[]): Promise<ITavilyExtractResponse>; // optional
    }
    
  2. Refactor TavilyEngine to implement it (no behavior change).
  3. Add PerplexityEngine targeting POST {baseUrl}/search with body { query, max_results, search_recency_filter, search_domain_filter } and Bearer-token auth (works against both api.perplexity.ai and LiteLLM-style proxies at /v1/search/perplexity-search).
  4. Settings:
    • websearch.engine: "tavily" | "perplexity" (default "tavily" — fully backwards compatible)
    • websearch.perplexity.baseUrl (default https://api.perplexity.ai)
    • Reuse the existing ApiKeySecretStorage pattern with a second auth provider id (e.g. perplexity), with env-var fallback.
  5. Perplexity response (results[].{title,url,snippet,...}) maps 1:1 onto the existing IWebSearchResults (no answer field — that's fine, it's optional and the extension already tolerates its absence when falling back to direct snippets).

The response-shape compatibility means the change is ~2 new files + small edits to chatTool.tsx / chatParticipant.ts / package.json.

Questions for maintainers

  • Are you open to a PR along these lines?
  • Preference on config shape: single engine enum switch, or per-tool overrides?
  • Should the Perplexity client's max_results / recency / domain_filter be exposed as tool parameters for the LM to control, or kept as settings only?

I'm willing to implement and test this end-to-end (including against a LiteLLM-proxied Perplexity route).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read src/search/webSearch.ts, src/search/webSearchTypes.ts, and src/chatTool.tsx first; trace how the current Tavily engine is selected and called. Then check src/chatParticipant.ts and package.json for integration points, and verify that both configured backends preserve the existing search result behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, vscode
Domain
api, search, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.