/**
 * Shared helpers for slot subflow builders.
 *
 * Pattern: utility module.
 * Role:    Tiny pure functions the slot builders share — hash, truncate,
 *          breakdown. Kept co-located to avoid cross-package import churn.
 */
import type { ContextSource, ContextSlot } from '../../events/types.js';
import type { BudgetPressureRecord, InjectionRecord, SlotComposition } from '../../recorders/core/types.js';
/**
 * Non-cryptographic stable hash — sufficient for InjectionRecord dedup.
 *
 * The implementation moved to `lib/fnv1a.ts` in 8.8.0 so the memory
 * layer's retrieval record can hash the same way without importing
 * `core/` (which imports `memory/` — the cycle is why a second copy was
 * the alternative). Re-exported here under the same name: every existing
 * importer of `helpers.fnv1a` is untouched, and there is still exactly
 * one implementation.
 */
export { fnv1a } from '../../lib/fnv1a.js';
/** Truncate with ellipsis for contentSummary fields. */
export declare function truncate(s: string, n: number): string;
/** Aggregate injection chars/count per source — payload for SlotComposition. */
export declare function breakdown(injections: readonly InjectionRecord[]): Readonly<Partial<Record<ContextSource, {
    chars: number;
    count: number;
}>>>;
/**
 * Build a SlotComposition summary record from injections + budget cap.
 * Drop tracking is opt-in — pass `dropped` when the slot actually
 * evicted anything during composition.
 */
export declare function composeSlot(slot: ContextSlot, iteration: number, injections: readonly InjectionRecord[], budgetCap: number, orderingStrategy?: string, dropped?: {
    count: number;
    summaries: readonly string[];
}): SlotComposition;
/**
 * Overflow detector for slot compositions.
 *
 * Returns a `BudgetPressureRecord` when `used > cap`, otherwise `null`.
 * `cap <= 0` is the "no budget" sentinel (see buildMessageApiChart's
 * `{ cap: 0, used: 0 }` composition) — it never overflows.
 *
 * `planAction: 'none'` is the honest answer: the built-in slots evict and
 * truncate NOTHING, so the full content went to the LLM and this record is
 * the loud signal that the slot's budget is not being respected.
 *
 * Units are CHARS, and the record says so: `unit` / `cap` / `projected`, added
 * in 8.14.0 and the only spelling since 9.0.0 removed the `*Tokens` names that
 * asserted a unit this channel does not use. A window strategy fills the same
 * fields with `unit: 'tokens'`, and one subscriber gets both.
 */
export declare function slotOverflow(composition: SlotComposition): BudgetPressureRecord | null;
/**
 * Human-facing warning text for a slot overflow. Says what actually
 * happened (nothing was truncated) and what to do about it — the typed
 * `context.budget_pressure` event carries the machine-readable truth.
 *
 * The unit is read off the record rather than written into the sentence, so
 * the words and the event can never disagree about what was counted.
 */
export declare function formatOverflowWarning(opts: {
    readonly pressure: BudgetPressureRecord;
    readonly itemCount: number;
    /** Singular noun for what filled the slot, e.g. 'tool definition'. */
    readonly itemNoun: string;
    /** Plural noun used in the "full … were sent" clause, e.g. 'definitions'. */
    readonly contentNoun: string;
    /** Actionable remedy sentence, ending with a period. */
    readonly remedy: string;
}): string;
