import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
export type ControllerStage = "idle" | "connecting" | "streaming" | "complete" | "error";
export type ControllerState = {
    readonly stage: "idle";
} | {
    readonly stage: "connecting";
    readonly executionId: string;
} | {
    readonly stage: "streaming";
    readonly executionId: string;
} | {
    readonly stage: "complete";
    readonly executionId: string;
} | {
    readonly stage: "error";
    readonly executionId: string;
    readonly error: Error;
};
/**
 * Callback interface for the stream controller to communicate with
 * its host (the React hook). All mutations to external state go
 * through these callbacks.
 */
export interface StreamControllerSink {
    /** Ingest a snapshot into the store (applies structural sharing). */
    ingestSnapshot(snapshot: AgentExecution): void;
    /** Transition the store's stream lifecycle state. */
    setStreamState(state: ControllerState): void;
}
/**
 * Framework-agnostic finite state machine that manages the lifecycle
 * of a single execution stream subscription.
 *
 * Responsibilities:
 * - Track FSM state transitions (idle → connecting → streaming → complete/error)
 * - Buffer incoming snapshots and coalesce via `requestAnimationFrame`
 * - Flush terminal snapshots immediately (no rAF delay)
 * - Provide abort/reconnect semantics
 *
 * This class has no React dependency. It communicates outward through
 * a {@link StreamControllerSink} and a `scheduleFlush` function
 * (typically `requestAnimationFrame`).
 */
export declare class StreamController {
    private _state;
    private _bufferedSnapshot;
    private _rafId;
    private _sink;
    private _scheduleFlush;
    private _cancelFlush;
    constructor(sink: StreamControllerSink, scheduleFlush?: (cb: () => void) => number, cancelFlush?: (id: number) => void);
    /** Current FSM state (read-only). */
    get state(): ControllerState;
    /**
     * Transition to `connecting` for the given execution ID.
     * If already active for a different ID, resets first.
     */
    start(executionId: string): void;
    /**
     * Handle an incoming snapshot from the gRPC stream.
     * Non-terminal snapshots are buffered for rAF coalescing.
     * Terminal snapshots flush immediately.
     */
    handleSnapshot(snapshot: AgentExecution): void;
    /**
     * Handle stream completion (iterator exhausted without error).
     * If we still have a buffered snapshot, flush it first.
     */
    handleStreamEnd(): void;
    /**
     * Handle a stream error. Flushes any buffered snapshot first
     * so the UI shows the last known good state alongside the error.
     */
    handleError(error: Error): void;
    /** Reset to idle. Cancels any pending flush. */
    reset(): void;
    /** Whether the controller has a buffered snapshot awaiting flush. */
    get hasPendingFlush(): boolean;
    private _activeExecutionId;
    private _transition;
    private _scheduleFlushOnce;
    private _flushBuffer;
    private _cancelPendingFlush;
}
//# sourceMappingURL=stream-controller.d.ts.map