/** * 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>>; /** * 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;