agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
72 lines (71 loc) • 3.44 kB
TypeScript
/**
* 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;