import type { LocalTrackPublication, Participant, ParticipantKind, RemoteTrackPublication, Room, TrackKind } from '@livekit/rtc-node';
import { AudioFrame, RemoteParticipant } from '@livekit/rtc-node';
import { type Throws, ThrowsPromise } from '@livekit/throws-transformer/throws';
import { ReadableStream } from 'node:stream/web';
import type { WebSocket } from 'ws';
/**
 * Recursively expands all nested properties of a type,
 * resolving aliases so as to inspect the real shape in IDE.
 */
export type Expand<T> = T extends Function ? T : T extends object ? T extends Array<infer U> ? Array<Expand<U>> : T extends Map<infer K, infer V> ? Map<Expand<K>, Expand<V>> : T extends Set<infer M> ? Set<Expand<M>> : {
    [K in keyof T]: Expand<T[K]>;
} : T;
/** Union of a single and a list of {@link AudioFrame}s */
export type AudioBuffer = AudioFrame[] | AudioFrame;
export declare const noop: () => void;
/** @internal */
export declare function waitForWebSocketOpen(ws: WebSocket, provider: string): Promise<void>;
export declare const isPending: (promise: Promise<unknown>) => Promise<Throws<boolean, Error>>;
/**
 * Merge one or more {@link AudioFrame}s into a single one.
 *
 * @param buffer - Either an {@link AudioFrame} or a list thereof
 * @throws
 * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError
 * | TypeError} if sample rate or channel count are mismatched
 */
export declare const mergeFrames: (buffer: AudioBuffer) => AudioFrame;
/** @internal */
export declare class Queue<T> {
    #private;
    /** @internal */
    items: T[];
    constructor(limit?: number);
    get(options?: {
        signal?: AbortSignal;
    }): Promise<T>;
    put(item: T): Promise<void>;
}
/** @internal */
export declare class Future<T = void, E extends Error = Error> {
    #private;
    constructor();
    get await(): ThrowsPromise<T, E>;
    get done(): boolean;
    get result(): T;
    /** Whether the future was rejected (cancelled) */
    get rejected(): boolean;
    resolve(value: T): void;
    reject(error: E): void;
}
/** @internal */
export declare class Event {
    #private;
    wait(): Promise<boolean>;
    get isSet(): boolean;
    set(): void;
    clear(): void;
}
/** @internal */
export declare class CancellablePromise<T, E extends Error = Error> {
    #private;
    constructor(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason: E) => void, onCancel: (cancelFn: () => void) => void) => void);
    get isCancelled(): boolean;
    get error(): Error | null;
    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | Promise<TResult1>) | null, onrejected?: ((reason: E) => TResult2 | Promise<TResult2>) | null): Promise<TResult1 | TResult2>;
    catch<TResult = never>(onrejected?: ((reason: E) => TResult | Promise<TResult>) | null): Promise<Throws<T | TResult | undefined, E>>;
    finally(onfinally?: (() => void) | null): Promise<Throws<T, E>>;
    cancel(): void;
    static from<T, E extends Error = Error>(promise: Promise<Throws<T, E>>): CancellablePromise<T, E>;
    static from<T>(promise: Promise<T>): CancellablePromise<T>;
}
/** @internal */
export declare function gracefullyCancel<T>(promise: CancellablePromise<T>): Promise<void>;
/** @internal */
export declare class AsyncIterableQueue<T> implements AsyncIterableIterator<T> {
    #private;
    private static readonly CLOSE_SENTINEL;
    get closed(): boolean;
    put(item: T): void;
    close(): void;
    next(options?: {
        signal?: AbortSignal;
    }): Promise<IteratorResult<T>>;
    [Symbol.asyncIterator](): AsyncIterableQueue<T>;
}
/** @internal */
export declare class ExpFilter {
    #private;
    constructor(alphaOrOpts: number | {
        alpha: number;
        initial?: number;
        minVal?: number;
        maxVal?: number;
    }, max?: number);
    reset(alphaOrOpts?: number | {
        alpha?: number;
        initial?: number;
        minVal?: number;
        maxVal?: number;
    }): void;
    apply(exp: number, sample: number): number;
    get filtered(): number | undefined;
    get value(): number | undefined;
    set alpha(alpha: number);
}
/** @internal */
export declare class AudioEnergyFilter {
    #private;
    constructor(cooldownSeconds?: number);
    pushFrame(frame: AudioFrame): boolean;
}
export declare enum TaskResult {
    Timeout = "timeout",
    Completed = "completed",
    Aborted = "aborted"
}
/** @internal */
/**
 * A task that can be cancelled.
 *
 * We recommend using the `Task.from` method to create a task. When creating subtasks, pass the same controller to all subtasks.
 *
 * @example
 * ```ts
 * const parent = Task.from((controller) => {
 *   const child1 = Task.from(() => { ... }, controller);
 *   const child2 = Task.from(() => { ... }, controller);
 * });
 * parent.cancel();
 * ```
 *
 * This will cancel all subtasks when the parent is cancelled.
 *
 * @param T - The type of the task result
 */
export declare class Task<T> {
    #private;
    private readonly fn;
    private readonly controller;
    readonly name?: string | undefined;
    private static readonly currentTaskStorage;
    private resultFuture;
    private doneCallbacks;
    /** Snapshot of the cancellation disposition, taken once at settlement. See {@link cancelled}. */
    private settledCancelled;
    constructor(fn: (controller: AbortController) => Promise<T>, controller: AbortController, name?: string | undefined);
    /**
     * Creates a new task from a function.
     *
     * @param fn - The function to run
     * @param controller - The abort controller to use
     * @returns A new task
     */
    static from<T>(fn: (controller: AbortController) => Promise<T>, controller?: AbortController, name?: string): Task<T>;
    /**
     * Returns the currently running task in this async context, if available.
     */
    static current(): Task<unknown> | undefined;
    private runTask;
    /**
     * Cancels the task.
     */
    cancel(): void;
    /**
     * Cancels the task and waits for it to complete.
     *
     * @param timeout - The timeout in milliseconds
     * @returns The result status of the task (timeout, completed, aborted)
     */
    cancelAndWait(timeout?: number): Promise<TaskResult.Completed | TaskResult.Aborted | (TaskResult.Completed & {
        __throws?(error: never): void;
    }) | (TaskResult.Aborted & {
        __throws?(error: never): void;
    })>;
    /**
     * The result of the task.
     */
    get result(): Promise<T>;
    /**
     * Whether the task has completed.
     */
    get done(): boolean;
    /**
     * Whether this task settled under a cancellation, the near-equivalent of asyncio's
     * `Task.cancelled()`. Needed because a cancelled body usually observes the abort signal and
     * returns normally rather than rejecting, so {@link result} alone cannot distinguish a task
     * that was torn down from one that ran to a real answer.
     *
     * Guarantees exactly: `true` if and only if the task is {@link done}, its controller was
     * already aborted at the instant it settled, and it did not fail with an error unrelated to
     * that abort (it either returned a value or rejected with an `AbortError`). The value is
     * captured once at settlement, so it is immutable afterwards — aborting the controller later
     * cannot reclassify a task that already finished.
     *
     * Does *not* guarantee:
     * - that the body was actually interrupted. A body that observes the abort and returns
     *   normally anyway still reports `true`; the abort, not the return, is the disposition.
     * - that this task specifically was the cancellation target. Controllers are intentionally
     *   shareable (see the class example), so an abort raised for a sibling before this task
     *   settles also marks it cancelled. Read this as "a cancellation was in effect for this
     *   task when it settled", not "someone called cancel() on this task".
     *
     * `false` while a cancelled task is still winding down, matching asyncio.
     *
     * @internal
     */
    get cancelled(): boolean;
    addDoneCallback(callback: () => void): void;
    removeDoneCallback(callback: () => void): void;
}
export declare function waitFor(tasks: Task<void>[]): Promise<void>;
export declare function cancelAndWait(tasks: Task<any>[], timeout?: number): Promise<void>;
export declare function withResolvers<T = unknown>(): {
    promise: ThrowsPromise<T, Error>;
    resolve: (value: T | PromiseLike<T>) => void;
    reject: (reason: Error) => void;
};
/**
 * Generates a short UUID with a prefix. Mirrors the python agents implementation.
 *
 * @param prefix - The prefix to add to the UUID.
 * @returns A short UUID with the prefix.
 */
export declare function shortuuid(prefix?: string): string;
/**
 * Creates a read-only proxy for an array.
 * @param array - The array to make read-only.
 * @param additionalErrorMessage - An additional error message to include in the error thrown when a mutation method is called.
 * @returns A read-only proxy for the array.
 */
export declare function createImmutableArray<T>(array: T[], additionalErrorMessage?: string): T[];
export declare function isImmutableArray(array: unknown): boolean;
/**
 * Resamples an audio stream to a target sample rate.
 *
 * WARINING: The input stream will be locked until the resampled stream is closed.
 *
 * @param stream - The input stream to resample.
 * @param outputRate - The target sample rate.
 * @returns A new stream with the resampled audio.
 */
export declare function resampleStream({ stream, outputRate, }: {
    stream: ReadableStream<AudioFrame>;
    outputRate: number;
}): ReadableStream<AudioFrame>;
export declare class InvalidErrorType extends Error {
    readonly error: unknown;
    constructor(error: unknown);
}
/**
 * Check if an error is a stream closed error that can be safely ignored during cleanup.
 * This happens during handover/cleanup when close() is called while operations are still running.
 *
 * @param error - The error to check.
 * @returns True if the error is a stream closed error.
 */
export declare function isStreamClosedError(error: unknown): boolean;
/**
 * Check if an error indicates writes to a closed WritableStream.
 *
 * @param error - The error to check.
 * @returns True if the error is a writable stream closed error.
 */
export declare function isWritableStreamClosedError(error: unknown): boolean;
/**
 * Check if an error is an expected FFmpeg teardown error that can be safely ignored during cleanup.
 *
 * @param error - The error to check.
 * @returns True if the error is an expected FFmpeg shutdown error.
 */
export declare function isFfmpegTeardownError(error: unknown): boolean;
/**
 * In JS an error can be any arbitrary value.
 * This function converts an unknown error to an Error and stores the original value in the error object.
 *
 * @param error - The error to convert.
 * @returns An Error.
 */
export declare function toError(error: unknown): Error;
/**
 * This is a hack to immitate asyncio.create_task so that
 * func will be run after the current event loop iteration.
 *
 * @param func - The function to run.
 */
export declare function startSoon(func: () => void): void;
export type DelayOptions = {
    signal?: AbortSignal;
};
/**
 * Delay for a given number of milliseconds.
 *
 * @param ms - The number of milliseconds to delay.
 * @param options - The options for the delay.
 * @returns A promise that resolves after the delay.
 */
export declare function delay(ms: number, options?: DelayOptions): Promise<void>;
export declare class IdleTimeoutError extends Error {
    constructor(message?: string);
}
/**
 * Race a promise against an idle timeout. If the promise does not settle within
 * `timeoutMs` milliseconds, the returned promise rejects with {@link IdleTimeoutError}
 * (or the error returned by `throwError` when provided).
 * The timer is properly cleaned up on settlement to avoid leaking handles.
 */
export declare function waitUntilTimeout<T, E extends Error = IdleTimeoutError>(promise: Promise<T>, timeoutMs: number, throwError?: () => E): Promise<Throws<T, E | IdleTimeoutError>>;
/** Result of {@link waitUntilAborted}: either the settled value, or an abort marker. */
export type Aborted<T> = {
    result: T;
    isAborted: false;
} | {
    result: undefined;
    isAborted: true;
};
/**
 * Race a promise against an `AbortSignal`. Unlike a plain reject-on-abort race,
 * this resolves with a tagged result so callers can branch on `isAborted`
 * instead of catching. On abort it resolves `{ result: undefined, isAborted: true }`;
 * otherwise it resolves `{ result, isAborted: false }`. A rejection of the
 * underlying promise is propagated. The abort listener is always cleaned up.
 *
 * An already-aborted signal short-circuits immediately to the abort result.
 *
 * Note: the underlying promise is not cancelled — it keeps running; this only
 * stops waiting for it. Because the promise is passed already-created, the
 * caller's operation has already started, so a pre-aborted signal won't prevent
 * that side effect (pass/await a factory yourself if you need to avoid starting it).
 */
export declare function waitUntilAborted<T>(promise: Promise<T>, signal: AbortSignal): Promise<Aborted<T>>;
/**
 * Returns a participant that matches the given identity. If identity is None, the first
 * participant that joins the room will be returned.
 * If the participant has already joined, the function will return immediately.
 * @param room - The room to wait for a participant in.
 * @param identity - The identity of the participant to wait for.
 * @param kind - The kind of the participant to wait for.
 * @returns A promise that resolves to the participant.
 */
export declare function waitForParticipant({ room, identity, kind, includeLocal, signal, }: {
    room: Room;
    identity?: string;
    kind?: ParticipantKind | ParticipantKind[];
    includeLocal: true;
    signal?: AbortSignal;
}): Promise<Participant>;
export declare function waitForParticipant({ room, identity, kind, includeLocal, signal, }: {
    room: Room;
    identity?: string;
    kind?: ParticipantKind | ParticipantKind[];
    includeLocal?: false;
    signal?: AbortSignal;
}): Promise<RemoteParticipant>;
export declare function waitForParticipantAttribute({ room, identity, attribute, value, signal, }: {
    room: Room;
    identity: string;
    attribute: string;
    value: string;
    signal?: AbortSignal;
}): Promise<void>;
export declare function waitForTrackPublication({ room, identity, kind, waitForSubscription, signal, includeLocal, }: {
    room: Room;
    identity?: string;
    kind: TrackKind;
    waitForSubscription?: boolean;
    signal?: AbortSignal;
    includeLocal: true;
}): Promise<RemoteTrackPublication | LocalTrackPublication>;
export declare function waitForTrackPublication({ room, identity, kind, waitForSubscription, signal, includeLocal, }: {
    room: Room;
    /**
     * Restrict matching to a specific participant identity. When omitted (or
     * `undefined`), matches whichever remote participant publishes a matching
     * track first. Rejects if the requested participant disconnects before a
     * matching publication is found. Pass `''` to match no one (rare, use
     * `undefined` instead).
     */
    identity?: string;
    kind: TrackKind;
    /**
     * If true, only resolve once the matching track is subscribed (i.e.
     * `publication.subscribed` is true and `publication.track` is set).
     * Mirrors python `wait_for_track_publication(wait_for_subscription=True)`.
     */
    waitForSubscription?: boolean;
    /**
     * Optional AbortSignal that rejects the promise and detaches all room
     * listeners when fired. Without this, callers that lose interest in the
     * publication leak listeners until the room disconnects.
     */
    signal?: AbortSignal;
    includeLocal?: false;
}): Promise<RemoteTrackPublication>;
/**
 * Yields values from a ReadableStream until the stream ends or the signal is aborted.
 * Handles reader cleanup and stream-release errors internally.
 */
export declare function readStream<T>(stream: ReadableStream<T>, signal?: AbortSignal): AsyncGenerator<T>;
export declare function toStream<T>(iterable: AsyncIterable<T>): ReadableStream<T>;
export declare function waitForAbort(signal: AbortSignal): Promise<Throws<void, Error>>;
export declare function rejectOnAbort(signal: AbortSignal): Promise<never>;
/**
 * Combines two abort signals into a single abort signal.
 * @param a - The first abort signal.
 * @param b - The second abort signal.
 * @returns A new abort signal that is aborted when either of the input signals is aborted.
 */
export declare const combineSignals: (a: AbortSignal, b: AbortSignal) => AbortSignal;
export declare const isCloud: (url: URL) => boolean;
/**
 * Whether the agent is running in development mode (launched via `dev` or `connect`).
 */
export declare const isDevMode: () => boolean;
/**
 * Whether the agent is hosted on LiveKit Cloud.
 */
export declare const isHosted: () => boolean;
export declare function asError(maybeError: unknown): Error;
/**
 * Resolve a value that may come from an explicit argument, one of several
 * environment variables (checked in order), or a final default.
 *
 * Used by inference transports to plumb credentials and URLs (e.g.
 * `LIVEKIT_REMOTE_EOT_URL`, `LIVEKIT_INFERENCE_API_KEY`).
 */
export declare function resolveEnvVar(value: string | undefined, envVars: readonly string[], defaultValue?: string): string;
/**
 * Tagged template literal that strips common leading indentation from every line,
 * trims the first empty line and any trailing whitespace.
 *
 * Useful for writing multi-line strings inside indented code without the indentation
 * leaking into the runtime value.
 *
 * @example
 * ```ts
 * const msg = dedent`
 *   Hello,
 *     world!
 * `;
 * // "Hello,\n  world!"
 * ```
 */
export declare function dedent(strings: TemplateStringsArray, ...values: unknown[]): string;
//# sourceMappingURL=utils.d.ts.map