import type { AttributionUnit, Embedder, UnitScore } from './types.js';
export interface ExplainChoiceArgs {
    /**
     * The chosen tool being explained. `text` is what gets embedded — pass
     * name + description (the name matters: a data snippet that NAMES the
     * thing the tool acts on, e.g. "id: d42", is its strongest citation).
     */
    readonly tool: {
        readonly name: string;
        readonly text: string;
    };
    /**
     * The context units, tagged by channel — e.g. `'system'` rules,
     * the `'task'`, `'data'` snippets from `snippetUnits`. Channels are
     * free-form strings; the verdict reports whatever labels it is given.
     */
    readonly units: readonly AttributionUnit[];
    /** Injected embedder. Wrap in an `EmbeddingCache` so rule texts embed once. */
    readonly embedder: Embedder;
    /** Abort signal threaded to the embedder (network backends). */
    readonly signal?: AbortSignal;
}
/** One channel's verdict: how much of the pick's positive similarity
 *  mass it owns, and the best unit inside it to quote. */
export interface ChannelVerdict {
    readonly channel: string;
    /**
     * 0..1 share of POSITIVE similarity mass (negatives are clamped out,
     * same as `attributeChoice.byChannel`). Shares across all channels sum
     * to ~1 — or are all 0 when no unit had positive similarity.
     */
    readonly share: number;
    /** The best-scoring unit IN this channel, text included for quoting.
     *  Omitted only when the channel has no units. */
    readonly top?: UnitScore & {
        readonly text: string;
    };
}
/** The full explanation for one tool pick — `attributeChoice` reshaped
 *  for display: text carried through, channels ranked. */
export interface ChoiceExplanation {
    /** The chosen tool being explained. */
    readonly tool: string;
    /**
     * One verdict per channel present in the units, sorted by share
     * descending (ties keep first-appearance order). Zero-share channels
     * are listed too — absence of pull is part of the verdict.
     */
    readonly channels: readonly ChannelVerdict[];
    /** The overall best unit — the citation ("picked because …"). */
    readonly top: UnitScore & {
        readonly text: string;
    };
    /** Every unit ranked descending (ties keep input order), text included. */
    readonly units: readonly (UnitScore & {
        readonly text: string;
    })[];
}
/**
 * Run `attributeChoice` and reshape the result for a UI: join each unit's
 * text back by id, pick the best unit per channel, and rank the channels
 * by their share of positive similarity mass.
 *
 * Fail-loud validation is inherited from `attributeChoice`: empty units
 * or duplicate unit ids throw — caller wiring bugs, not runtime conditions.
 */
export declare function explainChoice(args: ExplainChoiceArgs): Promise<ChoiceExplanation>;
