/**
 * Tool routing by decision model.
 *
 * The shipped router asks a generative model for `{servers: string[]}` on a
 * 15-second budget. That shape cannot express uncertainty: a server is in the
 * list or it is not, and the only recourse for a model that is unsure is to
 * include it. A decision model answers one yes/no question per server and
 * returns a *calibrated probability* for each, in one round trip of ~400ms
 * costing ~$0.00002.
 *
 * The asymmetry that follows is the whole point. Keeping a server that was not
 * needed costs a few hundred tokens of tool definitions. Dropping a server
 * that WAS needed costs the turn — the model cannot call a tool it was never
 * shown, and it has no way to ask for it back. So a server is excluded only on
 * a *confident no*; unanswered, mistyped and near-coin-flip answers all keep
 * it. This is the same reasoning as the classifier's asymmetric upgrade and
 * downgrade bars, applied to a different decision.
 *
 * Fail-open in every direction: returns `null` whenever the caller should
 * carry on as if this module did not exist.
 *
 * @module core/toolRoutingDecision
 */
import type { DecisionCallerFn, ToolRoutingCatalogEntry, ToolRoutingDecisionOutcome } from "../types/index.js";
/**
 * Ask one yes/no question per routable server and return the servers to keep.
 *
 * Returns `null` when the caller should fall through to its existing path:
 * no decision provider, a failed call, fewer than two servers, or an answer
 * set that would change nothing.
 */
export declare function selectServersByDecision(userQuery: string, routableServers: ToolRoutingCatalogEntry[], decide: DecisionCallerFn, options?: {
    timeoutMs?: number;
    minDropConfidence?: number;
}): Promise<ToolRoutingDecisionOutcome | null>;
