/**
 * budget-state — Per-run budget + coherence + compaction primitives for the
 * Vauban agent loops.
 *
 * Scope:
 *   - AgentBudgetState (mutable counters: steps, tokens, context window).
 *   - CoherenceDetector: flags tool-call loops and stalls.
 *   - compactToolLog: trims the middle of a long tool conversation.
 *   - emergencyContextSummary: LLM-backed "last resort" fallback when the
 *     context window passes 90% of its soft cap.
 *
 * Non-goals:
 *   - Token counting / tokenizer accuracy (provider-router returns usage).
 *   - Persistence of budget state (AgentRunTracker handles that).
 */
export interface AgentBudgetState {
    stepCount: number;
    maxSteps: number;
    tokensBudget: {
        input: number;
        output: number;
        usedInput: number;
        usedOutput: number;
    };
    contextWindow: {
        maxTokens: number;
        currentTokens: number;
    };
    /** stepCount value at which compactToolLog should run. */
    compactionTrigger: number;
    /** 0..1 — live coherence score (1 = healthy, 0 = loop+stall). */
    coherenceScore: number;
}
export interface CoherenceDetector {
    check(recentToolCalls: Array<{
        name: string;
        args: unknown;
    }>, stepsWithoutTool: number): {
        isLoop: boolean;
        isStall: boolean;
        score: number;
    };
}
export type LogMessage = {
    role: "user" | "assistant" | "tool" | "system";
    content: string;
    toolName?: string;
};
export declare function createBudgetState(overrides?: Partial<AgentBudgetState>): AgentBudgetState;
/**
 * Returns a detector that flags:
 *   - loop   : last `loopDetectionWindow` tool calls have identical name + deep-equal args.
 *   - stall  : `stepsWithoutTool >= stallThreshold` (assistant keeps answering
 *              but never invokes a tool).
 *
 * Score: 1.0 if neither, 0.0 if both, 0.5 if exactly one.
 */
export declare function createCoherenceDetector(config?: {
    loopDetectionWindow?: number;
    stallThreshold?: number;
}): CoherenceDetector;
/**
 * Keeps the first `keepFirst` and last `keepLast` messages; replaces the
 * middle with a single system note describing how many steps were omitted.
 *
 * Guarantees:
 *   - Returns a NEW array (does not mutate input).
 *   - If log is already short enough, returns a copy unchanged.
 *   - Never drops the very first user message (prompt context).
 */
export declare function compactToolLog(log: LogMessage[], opts?: {
    keepFirst?: number;
    keepLast?: number;
}): LogMessage[];
export interface DecayCompactionConfig {
    /** Half-life in turns. Default 4. */
    halfLifeTurns?: number;
    /** Bonus added to tool-error scores. Default 0.3. */
    errorBonus?: number;
    /** Maximum tool messages to keep. Default 12. */
    keepTopK?: number;
}
/**
 * Decay-weighted alternative to compactToolLog.
 * Preserves system + user messages always. Among tool messages, scores
 * by recency × content-richness × error-flag and keeps the top-K by
 * score, restored to original chronological order.
 *
 * Score formula (Ebbinghaus-inspired, ref: MemoryBank Zhong et al. AAAI 2024):
 *   recency  = 0.5 ^ (turns_from_end / halfLifeTurns)   [1.0 = most recent]
 *   size     = log(content.length + 1) / 10             [slight richness boost]
 *   errBonus = 0.3 if content looks like a tool error    [remember failures]
 *   score    = recency + size + errBonus
 *
 * System and user messages are NEVER evicted.
 * Returns a NEW array (does not mutate input).
 */
export declare function compactToolLogDecay(log: LogMessage[], config?: DecayCompactionConfig): LogMessage[];
/**
 * Called when contextWindow.currentTokens > 0.9 * maxTokens. Uses the
 * caller-provided `summarize` function (typically the provider-router's
 * complete() wired as a one-shot prompt) to produce a short recap that
 * replaces the bulk of the log.
 *
 * Recursion guard: `opts.recursion` MUST be false. If callers ever wire
 * this into itself (e.g. summarize triggers another context summary), it
 * throws — we refuse to recurse because the error path must be bounded.
 */
export declare function emergencyContextSummary(log: LogMessage[], summarize: (prompt: string) => Promise<string>, opts: {
    recursion: false;
}): Promise<string>;
//# sourceMappingURL=budget-state.d.ts.map