import type { ToolDef } from './provider-base.js';
import type { ToolDispatcher } from './tool-dispatcher.js';
export declare function isWebToolName(name: string): boolean;
export declare function getWebTools(): ToolDef[];
export declare function buildWebDispatcher(): ToolDispatcher;
interface SearchHit {
    title: string;
    url: string;
    snippet: string;
}
/**
 * v1.2.118 — pluggable search-provider interface. Each provider:
 *   - `name` is the env-config token (e.g. 'tavily')
 *   - `available()` short-circuits the chain when required keys are
 *     missing (so a fresh agim install without TAVILY_API_KEY skips
 *     Tavily without logging an error every search)
 *   - `search()` returns ≥0 SearchHit; an empty array means "no hits"
 *     and triggers fallback to the next provider, while a throw means
 *     "transient error" and is also followed by fallback (logged at
 *     warn). Either way, the chain continues until exhaustion.
 */
interface SearchProvider {
    name: string;
    available(): boolean;
    search(query: string, n: number, signal: AbortSignal): Promise<SearchHit[]>;
}
/**
 * Read `IMHUB_WEB_SEARCH_PROVIDERS` (CSV) and return the active chain.
 * Unknown names are dropped with a one-shot warn (so a typo doesn't
 * silently disable the entire chain). Providers whose `available()`
 * returns false are also dropped — these are NOT logged because the
 * common case is "key not set, skip", not a misconfig.
 */
export declare function resolveSearchProviderChain(): SearchProvider[];
/**
 * v1.2.126 — descriptor used by the SPA search settings page. Lists
 * every registered provider (whether in the env chain or not), with
 * its key-requirement flag and current availability so the operator
 * can see "Tavily ✓ configured / Brave ⚠ missing key" at a glance.
 */
export interface SearchProviderInfo {
    name: string;
    envKey: string | null;
    available: boolean;
}
/** All known providers + each provider's env requirement & current
 *  availability. Order matches DEFAULT_PROVIDER_ORDER so the SPA can
 *  render a stable list when no env chain is configured. */
export declare function listAllSearchProviders(): SearchProviderInfo[];
/** Look up a single provider by name. Returns null if unknown — the
 *  caller (e.g. /api/search/test) is expected to surface that as a
 *  400 with the supported names. */
export declare function getSearchProviderByName(name: string): SearchProvider | null;
export declare function parseBraveResults(data: unknown, max: number): SearchHit[];
export declare function parseSerperResults(data: unknown, max: number): SearchHit[];
export declare function parseExaResults(data: unknown, max: number): SearchHit[];
/** Parse Tavily's `{results: [{title, url, content, score}]}` shape.
 *  Tolerant of missing fields: a hit needs title + url to be usable. */
export declare function parseTavilyResults(data: unknown, max: number): SearchHit[];
/** Tiny extractor for the DuckDuckGo HTML SERP. The DDG HTML page wraps
 *  each result in `<div class="result">` with `<a class="result__a" href="...">title</a>`
 *  + `<a class="result__snippet">snippet</a>`. We don't use a DOM parser
 *  (no dep), just regex — robust enough for SERPs (DDG is stable about
 *  these classes). */
export declare function parseDdgHtml(html: string, max: number): SearchHit[];
/** Best-effort metaso response normaliser. Field names from metaso vary
 *  with API version; we look at common shapes. Adjust here if metaso
 *  changes their schema.
 *
 *  As of 2026-06-01 the public POST /api/v1/search returns
 *  `{ webpages: [{ title, link, snippet, score, position, date }], total }`.
 *  Older endpoints used `data.list[]` / `results[]` / `items[]` — kept
 *  for compatibility so a transparent rollback in metaso doesn't break
 *  us. v1.2.128 hotfix: previously we missed `webpages` and parsed 0
 *  hits on every call, which surfaced as "测试 ✓ 0 hits" in the admin
 *  UI's per-provider test button (#agim-issue 2026-06-01). */
export declare function parseMetasoResults(data: unknown, max: number): SearchHit[];
interface SafetyResult {
    ok: boolean;
    reason?: string;
}
export declare function checkUrlSafety(raw: string): SafetyResult;
/**
 * v1.2.70 — IPv4 parser that accepts every form Node's URL parser
 * also accepts:
 *   - dotted quad      "127.0.0.1"
 *   - 3-part           "127.1" (rare but valid per RFC 3986)
 *   - decimal integer  "2130706433"
 *   - hex integer      "0x7f000001" / "0x7f.0.0.1"
 *   - octal            "0177.0.0.1"
 * Returns the 4-octet form or null if the input isn't a valid IPv4
 * representation. Validates each octet's range, closing CR-3
 * (999.999.999.999 overflow) — any out-of-range part → null.
 */
export declare function tryParseIPv4Variants(host: string): [number, number, number, number] | null;
/** Expand `addr` (already validated by net.isIPv6) into 8 × 16-bit
 *  groups. Returns null only if the form somehow can't be normalized
 *  (shouldn't happen post-net.isIPv6).
 */
export declare function expandIpv6(addr: string): number[] | null;
interface Cidr4 {
    network: number;
    mask: number;
}
export declare function parseSsrfWhitelist(raw: string | undefined): Cidr4[];
export {};
//# sourceMappingURL=web-dispatcher.d.ts.map