/**
 * companion-chat-rate-limiter.ts
 *
 * Token-bucket rate limiter for CompanionChatManager.
 *
 * Enforces two independent limits:
 *   - per-client: max N messages/minute across all sessions for a given clientId.
 *   - per-session: max M messages/minute for a given sessionId regardless of client.
 *
 * When a limit is exceeded, throws GoodVibesSdkError with kind='rate-limit',
 * including an actionable message following the standard three-part format:
 *   [what happened] · [why] · [what to do]
 */
import type { ConfigManager } from '../config/manager.js';
export declare const DEFAULT_MESSAGES_PER_MINUTE_PER_CLIENT = 30;
export declare const DEFAULT_MESSAGES_PER_MINUTE_PER_SESSION = 10;
/**
 * Maximum number of distinct clientId/sessionId buckets to track concurrently.
 * A slow attacker sending requests with distinct IDs would otherwise grow the
 * Map without bound between cleanup() cycles. LRU eviction caps the attack
 * surface at O(MAX_BUCKETS) entries per map.
 */
export declare const MAX_RATE_LIMITER_BUCKETS = 10000;
/**
 * Read the per-session threshold override from the environment.
 * GOODVIBES_CHAT_LIMITER_THRESHOLD=<int> overrides the per-session limit.
 * Returns undefined when unset or not a positive integer.
 */
export declare function readThresholdFromEnv(env?: NodeJS.ProcessEnv): number | undefined;
export interface CompanionChatRateLimiterOptions {
    /** Max messages per 60-second window per clientId. Default: 30. */
    readonly perClientLimit?: number | undefined;
    /**
     * Max messages per 60-second window per sessionId. Default: 10.
     *
     * **Startup-time env var**: `GOODVIBES_CHAT_LIMITER_THRESHOLD` is read **once** at
     * constructor time and used when this option is not provided. It
     * cannot be changed at runtime without a daemon restart.
     *
     * **Runtime config key**: `runtime.companionChatLimiter.perSessionLimit` is read
     * on every `check()` call (when a `configManager` is provided) and takes
     * precedence over the env-var-captured default.
     */
    readonly perSessionLimit?: number | undefined;
    /** Window size in ms. Default: 60000 (1 minute). */
    readonly windowMs?: number | undefined;
    /**
     * Optional ConfigManager for runtime lookup of
     * `runtime.companionChatLimiter.perSessionLimit`.
     * When provided, `check()` reads this key on each call and uses it as the
     * effective per-session limit (falling back to the constructor-time value
     * when the config key is absent or not a positive integer).
     */
    readonly configManager?: Pick<ConfigManager, 'get'> | null | undefined;
}
export declare class CompanionChatRateLimiter {
    private readonly perClientLimit;
    /**
     * Base per-session limit: resolved at constructor time from explicit option >
     * env var > compile-time default. May be overridden per-call by the config
     * manager when `configManager` is provided.
     *
     * **Note**: `GOODVIBES_CHAT_LIMITER_THRESHOLD` is read **once** at constructor
     * time and cached here. Changing the env var after daemon startup has no effect
     * without a daemon restart. Use the `runtime.companionChatLimiter.perSessionLimit`
     * config key for live changes.
     */
    private readonly perSessionLimitBase;
    private readonly windowMs;
    private readonly configManager;
    /** clientId → bucket */
    private readonly clientBuckets;
    /** sessionId → bucket */
    private readonly sessionBuckets;
    constructor(options?: CompanionChatRateLimiterOptions, env?: NodeJS.ProcessEnv);
    /**
     * Resolve the effective per-session limit for the current call.
     *
     * Runtime config key `runtime.companionChatLimiter.perSessionLimit` takes
     * precedence over the constructor-time baseline when it resolves to a
     * positive integer.
     */
    private resolvePerSessionLimit;
    /**
     * Check and record a message attempt.
     *
     * Throws GoodVibesSdkError{kind:'rate-limit'} if either limit is exceeded.
     * On success, the attempt is recorded in both buckets.
     *
     * @param sessionId - The session receiving the message.
     * @param clientId  - The client sending the message (use '' to skip per-client check).
     */
    check(sessionId: string, clientId: string): void;
    /** Remove stale buckets to prevent unbounded memory growth. */
    cleanup(): void;
    private getOrCreate;
}
//# sourceMappingURL=companion-chat-rate-limiter.d.ts.map