/**
 * External-agent process pool (A).
 *
 * Keeps spawned external ACP agents (Codex/Claude/etc.) alive and reuses them across chat turns,
 * instead of the spawn → one turn → kill cycle that paid a full ACP cold-start (several seconds)
 * on every message. Reuse also gives external agents real multi-turn memory (same ACP session).
 *
 * Design (mirrors how VSCode keeps language-server-style agent CLIs resident):
 *  - One AgentProcessManager + one spawned member per pool key (agentId + cwd + sessionId).
 *  - The first turn spawns + registers; subsequent turns reuse the live member (sendTask only).
 *  - A mutable `holder.current` carries the *current* turn's identity so the manager's
 *    construction-time onNotification can tag live deltas with the right turn (see agents-handler).
 *  - Idle entries are reaped after IDLE_TTL_MS; the pool is bounded to MAX_POOL by LRU eviction.
 *  - Busy entries (a turn in flight) are never evicted.
 */
import type { AgentProcessManager } from "./agent-process.js";
/** Mutable per-turn context read by the pooled manager's onNotification callback. */
export interface PooledTurnCtx {
    sessionId?: string;
    turnId?: string;
    requestId?: string;
    deltas: string[];
    streamedAny: boolean;
}
export interface PooledAgentEntry {
    manager: AgentProcessManager;
    memberId: string;
    /** Boxed so the manager's onNotification (built before registration) can read the live turn. */
    holder: {
        current: PooledTurnCtx | null;
    };
    lastUsed: number;
}
/** Pool key: same agent + workspace + session ⇒ same resident process (and shared memory). */
export declare function poolKey(agentId: string, cwd: string, sessionId?: string): string;
/** Return a live pooled entry for the key, or undefined (evicting a dead one if found). */
export declare function getAlivePooledAgent(key: string): PooledAgentEntry | undefined;
/** Register a freshly-spawned entry, evicting any stale same-key entry and enforcing MAX_POOL. */
export declare function registerPooledAgent(key: string, entry: PooledAgentEntry): void;
/**
 * Re-key a pre-warmed entry (spawned before a session existed, under WARM_SESSION) onto the real
 * session key, so the first turn adopts the warmed process and skips the cold start. Does not
 * dispose — the same live process is moved. Returns undefined if no live warmed entry exists.
 */
export declare function adoptWarmedAgent(warmKey: string, sessionKey: string): PooledAgentEntry | undefined;
/** Reserved session token for a process pre-warmed before its real session id is known. */
export declare const WARM_SESSION = "__warm__";
/** Drop + dispose a single entry (e.g. after a turn errors and the process is suspect). */
export declare function evictPooledAgent(key: string): void;
/** Kill + dispose every pooled agent and stop the reaper. Call on agent shutdown. */
export declare function disposeAllPooledAgents(): void;
export declare function pooledAgentCount(): number;
/** Reap idle (non-busy) entries past the TTL. Exposed for deterministic testing. */
export declare function reapIdlePooledAgents(now: number): void;
