/**
 * SessionStateBag — typed container for the per-session state previously held
 * as private fields on `AgentService` (six `Map<sessionKey, …>` instances with
 * no shared cleanup path).
 *
 * Goals:
 * - Single `disposeSession(sessionKey)` entry that clears every slot for a key
 *   (and runs the event unsubscriber, which was easy to forget previously).
 * - Optional TTL sweep for slots whose lifecycle is not bound to an explicit
 *   register/unregister pair, so long-running Gateways do not accumulate stale
 *   per-session entries from disconnected webchat clients or finished turns.
 * - Hard upper bound for the same TTL'd slots to bound worst-case memory.
 *
 * Slots whose lifetime is fully owned by explicit lifecycle calls
 * (`inboundTurnDepth`, `directStreamOutcome`, `embeddedStreamText`,
 * `sessionEventUnsubscribers`) are still cleared via `disposeSession`, but they
 * are NOT subject to TTL — sweeping them would race with their owners.
 */
export type WebchatSsePublisher = (event: {
    type: string;
    [key: string]: unknown;
}) => void;
export interface PersistentGoalStreamOutcome {
    skipPersistentGoalPostTurn: boolean;
}
export interface SessionStateBagOptions {
    /** Idle TTL for TTL-managed slots. Defaults to 1 hour. Set to 0 to disable sweeping. */
    ttlMs?: number;
    /** Sweep cadence. Defaults to 10 minutes. */
    sweepIntervalMs?: number;
    /** Hard upper bound on entries for TTL-managed slots. Defaults to 5000. */
    maxEntries?: number;
    /** Inject a clock for tests. */
    now?: () => number;
}
export declare class SessionStateBag {
    /** Webchat SSE publisher (register/unregister + TTL fallback). */
    private readonly webchatPublishers;
    /** Last assistant plain text (TTL + LRU). */
    private readonly lastAssistantText;
    /** Stream text for the in-flight embedded turn (managed by turn). */
    private readonly embeddedStreamText;
    /** Persistent-goal stream outcome (take-and-delete). */
    private readonly directStreamOutcome;
    /** Concurrent inbound turn depth (counter). */
    private readonly inboundTurnDepth;
    /** Agent-event subscription tear-downs (run on dispose). */
    private readonly sessionEventUnsubscribers;
    private readonly ttlMs;
    private readonly maxEntries;
    private readonly now;
    private readonly sweepTimer;
    constructor(opts?: SessionStateBagOptions);
    registerWebchatPublisher(sessionKey: string, publisher: WebchatSsePublisher): void;
    unregisterWebchatPublisher(sessionKey: string): void;
    getWebchatPublisher(sessionKey: string): WebchatSsePublisher | undefined;
    setLastAssistantText(sessionKey: string, text: string): void;
    getLastAssistantText(sessionKey: string): string | undefined;
    appendEmbeddedStreamText(sessionKey: string, chunk: string): string;
    clearEmbeddedStreamText(sessionKey: string): void;
    recordPersistentGoalStreamOutcome(sessionKey: string, outcome: PersistentGoalStreamOutcome): void;
    takePersistentGoalStreamOutcome(sessionKey: string): PersistentGoalStreamOutcome | undefined;
    beginInboundTurn(sessionKey: string): void;
    endInboundTurn(sessionKey: string): void;
    getInboundTurnDepth(sessionKey: string): number;
    setSessionEventUnsubscriber(sessionKey: string, unsubscribe: () => void): void;
    hasSessionEventUnsubscriber(sessionKey: string): boolean;
    /** Clear every slot for `sessionKey`, invoking the unsubscriber if registered. */
    disposeSession(sessionKey: string): void;
    /** Tear down every session (process stop / hot reload). */
    disposeAll(): void;
    /** Test helper. */
    size(): {
        webchatPublishers: number;
        lastAssistantText: number;
        embeddedStreamText: number;
        directStreamOutcome: number;
        inboundTurnDepth: number;
        sessionEventUnsubscribers: number;
    };
    private sweepStaleEntries;
    private enforceCap;
}
