import type { FlowChartBuilder } from 'footprintjs';
import type { MemoryState } from './types.js';
import { type TokenCounter } from './tokenize.js';
/**
 * Reusable shape for a **composable pipeline segment** — a function that
 * appends one or more stages to a builder and returns the builder. This
 * is the memory layer's convention for packaging multi-stage work
 * (decider + branches, multi-stage sub-pipelines) as a single unit that
 * consumers can drop into any flowchart:
 *
 * ```ts
 * let b = flowChart<MyState>('Seed', seed, 'seed');
 * b = pickByBudget(config)(b);          // appends a decider + 3 branches
 * b = b.addFunction('Format', fmt, ...);
 * ```
 *
 * Generic in `T` so segments targeting the memory layer can be composed
 * into host flowcharts whose state extends `MemoryState`. Future
 * segments (NarrativeMemory, SemanticRetrieval, FactExtraction) follow
 * the same shape for uniform composition ergonomics.
 */
export type PipelineSegment<T extends object> = (builder: FlowChartBuilder<T>) => FlowChartBuilder<T>;
export interface PickByBudgetConfig {
    /**
     * Tokens to keep in reserve — not used for memory. Default 256.
     * Covers system-prompt overhead, new user message headroom, and safety
     * margin against token-counter approximation error. Tune per model.
     */
    readonly reserveTokens?: number;
    /**
     * Hard floor on memory tokens. If the budget minus reserve is less than
     * this, NO memory is injected (better to skip than inject a fragment).
     * Default 100 — under 100 tokens of memory is usually worse than none.
     */
    readonly minimumTokens?: number;
    /**
     * Pluggable token counter — defaults to `approximateTokenCounter`
     * (1 token ≈ 4 chars). Swap for a real tokenizer when accuracy matters.
     */
    readonly countTokens?: TokenCounter;
    /**
     * Optional cap on the NUMBER of entries, independent of tokens.
     * Useful when the budget is large enough to include hundreds of
     * entries but the LLM's "lost-in-the-middle" effect degrades quality
     * past ~20. Default: no cap (budget is the only limit).
     */
    readonly maxEntries?: number;
}
/**
 * Append the pick-by-budget decider + branches to `builder`. Returns
 * the builder so calls chain naturally:
 *
 * ```ts
 * let b = flowChart<MemoryState>('LoadRecent', loadRecent(config), 'load-recent');
 * b = pickByBudget(pickConfig)(b);
 * b = b.addFunction('Format', formatDefault(formatConfig), 'format-default');
 * ```
 *
 * Generic in `T` so consumers whose scope extends `MemoryState` (e.g.,
 * an AgentLoopState that embeds memory fields) can compose this into
 * their own pipeline without casting.
 */
export declare function pickByBudget<T extends MemoryState = MemoryState>(config?: PickByBudgetConfig): PipelineSegment<T>;
