Skip to content

[Feature]: Choose the web search provider, with Serply as a second option #459

Open

Description

@googio

Problem / pain point

Web research (#433, settings in #439) only works with a Tavily key. A user who already pays for a different search API, or whose organization has approved a different one, has to open a Tavily account before research slides can cite anything. WEB_SEARCH.md already says the tool contract is provider-independent. The only Tavily-specific parts are the key slot (secrets['tavily']), the request in web-research-network.ts, and the Settings copy.

Proposed solution

Add a provider choice to the existing Web Search settings, and ship Serply as the second adapter. Everything else would stay as it is:

  • Config: an optional webSearch.provider field, 'tavily' | 'serply', defaulting to 'tavily'. Existing configs and saved keys keep working with no migration.
  • Keys: each provider has its own slot (secrets['tavily'], secrets['serply']) in the same safe: / plain: store. Switching providers never moves or exposes a key.
  • Settings > Web Search: a provider selector above the key field. Get, save and test keep returning status codes only, now for the selected provider.
  • Adapter: GET https://api.serply.io/v1/search?q=...&num=... with an X-Api-Key header. results[].title/link/description map onto the current result shape, within the same 1 to 5 result and 2,000 character snippet limits. The network rules for search requests don't change.
  • Unchanged: the permission prompt, maxCalls, page fetching, and "no automatic fallback". Only one provider is active at a time.
  • Rest of the change: en and zh-CN strings, WEB_SEARCH.md, tests next to the existing Tavily ones, and a changeset.

I'd build and maintain the PR. If you'd rather review it in two steps, I can send the provider field (with Tavily as the only option) first and the Serply adapter second.

Disclosure: I work with Serply.

Alternatives considered

  • A generic "custom endpoint" provider: rejected. Search APIs differ in auth, request and response shape, so this would need a mapping DSL, which is more surface than one small adapter.
  • Replacing Tavily: not proposed. It stays the default.

Scope

Provider / model

Hard-constraints check

  • I have read the hard constraints in CLAUDE.md and this proposal does not conflict with any of them (BYOK only, no proxy, no new dependency, no new credential store).

Activity

  1. github-actions commented on Oct 2, 2026

    @github-actions
    Contributor

    Thanks for the thorough write-up, and for the Serply disclosure up front — that's genuinely helpful for review. A provider-selectable Web Search slot with Tavily as the default plus one additional adapter is a reasonable, well-bounded direction, and the scope you list matches how the current Tavily integration is already laid out. This reads as an extension of the earlier web-research work (#433, #439) rather than a duplicate.

    What lines up with the current design:

    • The existing integration is already search-only and settings-driven. .changeset/tavily-settings-entry.md describes safe key save/replace/clear with bounded connection testing, applying settings to new runs "without restarting while retaining per-run networking consent and active-run snapshots", and keeping search-only credentials out of the model API service list. A second adapter reuses that same shape — consent, per-run snapshots, and the no-automatic-fallback behavior stay as they are.
    • .changeset/preserve-web-search-settings.md shows web-search opt-in and limits are already preserved across provider/model changes, config imports, image settings, and design-system saves, so an optional webSearch.provider field should ride that same persistence path instead of adding a second one.
    • The adapter is app code over the existing HTTP path — no new shipped dependency, so the permissive-dependency constraint isn't triggered.

    Things worth pinning down before the PR:

    • On-disk config should carry the schemaVersion field (per CLAUDE.md: "Schema-version everything that lives on disk") with 'tavily' as the default, so existing installs migrate with no user action.
    • Repo guidance says to avoid config-driven dispatch "unless we have two real callers" (CLAUDE.md). Shipping both providers at once satisfies that; the two-step split (field with Tavily only first) would land a dispatcher with a single caller. Either ordering is workable — a maintainer may have a preference.
    • Keeping each provider's key strictly in its own slot, with no move or copy on switch, is the right call and matches your proposal.

    Need more info:

    • Should maxCalls, the 1–5 result count, and the 2,000-character snippet cap stay shared across providers, or can they be provider-specific?
    • Will the Serply adapter stay under the same opt-in networking rules as the current search requests, with no new host beyond api.serply.io?
    • Do you want the first PR to include the provider selector and en / zh-CN strings for both providers, or land the selector with Tavily only and add Serply routing in the follow-up?

    Open-CoDesign Bot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions