/** * `web.search` registry handler: resolves the active * {@link SearchProviderId}, looks up its API key, dispatches a single * outbound request per provider (no retry of the *same* provider), * validates/truncates the hits to `maxResults`, and emits one audit-log * entry per attempt. Failures surface as `ok=false` with a categorical * `error.kind` naming the provider. * * DuckDuckGo fallback: DuckDuckGo is the keyless default and regularly * returns anti-bot challenges (HTTP 202) or upstream 502/5xx responses on * shared or rate-limited networks. When the active provider is DuckDuckGo * and it fails, the handler transparently falls back to a keyed provider * — Exa first, then Tavily, then Brave — whenever a key is configured for * it. Each * fallback is a single attempt against a *different* provider, so the * per-provider single-attempt contract (Requirement 6.7) is preserved. * * Provider modules self-register into {@link searchProviders} on import, * so they're eagerly imported here. */ import type { ToolResult } from "../../types.js"; import type { ToolRunOptions } from "../registry.js"; import { type SearchProvider } from "./providers/provider.js"; import "./providers/duckduckgo.js"; import "./providers/brave.js"; import "./providers/tavily.js"; import "./providers/exa.js"; import { type SearchProviderId, type WebSearchArgs, type WebSearchErrorKind, type WebSearchOutcome } from "./types.js"; /** * Optional injection points for tests so the search dispatch can be * exercised without invoking the real provider modules. Production * callers never pass these. */ export interface WebSearchOptions extends ToolRunOptions { /** Override the active provider lookup. */ provider?: SearchProviderId; /** Override the registered {@link SearchProvider} for the active id. */ providerOverride?: SearchProvider; /** Override the API-key resolver. Returns the raw key (or undefined). */ resolveKey?: (id: SearchProviderId) => Promise; /** Wall-clock timeout in milliseconds. Default: {@link SEARCH_TIMEOUT_MS}. */ timeoutMs?: number; } /** * Run `web.search`. Always emits a single audit-log entry. Never * throws — every failure mode surfaces as `ok=false`. */ export declare function webSearch(args: WebSearchArgs, options?: WebSearchOptions): Promise; export type { WebSearchOutcome, WebSearchErrorKind };