/**
 * AudinOperator — the public entry point of `@audin.ai/operator-sdk`.
 *
 * A headless (no-UI) controller an operator's browser app drives to make and
 * receive phone calls through Audin. It hides:
 *   - the signalling channel (PresenceClient: availability, ringing, dialing),
 *   - the media channel (AudioBridge: microphone, μ-law transcoding, playback),
 *   - reconnection, heartbeats and token refresh.
 *
 * Credentials never enter the browser: the app supplies a `getToken` callback
 * that calls ITS OWN backend (which holds the account key) to mint a
 * short-lived session token. The SDK only ever sees that token.
 *
 * MVP concurrency: ONE active call at a time. While a call is live, an inbound
 * offer is auto-declined (`reject`) and `dial()` rejects with an error. This
 * keeps the audio graph and state machine simple; multi-line can layer on top
 * later without changing the public surface.
 *
 * Naming is provider-neutral throughout — this is "the Audin operator
 * softphone", nothing more.
 */
import { TypedEmitter } from "./emitter.js";
import type { AudinOperatorConfig, AudinOperatorEventMap, AudinOperatorEventName, AudinOperatorListener, DialOptions, OperatorCall, OperatorPhoneNumber, PresenceState } from "./types.js";
export declare class AudinOperator extends TypedEmitter<AudinOperatorEventMap> {
    private readonly presence;
    private readonly coreWsHost;
    private readonly coreHttpBase;
    private readonly tokens;
    /**
     * Microphone constraints handed to the next {@link AudioBridge} when a call's
     * audio leg opens. Mutable so {@link setAudioConstraints} can switch the input
     * device at runtime; read fresh in {@link openAudioBridge} (never captured
     * earlier), so the change applies from the next call.
     */
    private audioConstraints;
    private readonly logger;
    private presenceState;
    /** The single active/ringing call (MVP: one at a time). */
    private activeCall;
    private activeBridge;
    /** Pending outbound dial awaiting its `outbound_started` ack. */
    private pendingOutbound;
    constructor(config: AudinOperatorConfig);
    on<K extends AudinOperatorEventName>(event: K, listener: AudinOperatorListener<K>): () => void;
    off<K extends AudinOperatorEventName>(event: K, listener: AudinOperatorListener<K>): void;
    once<K extends AudinOperatorEventName>(event: K, listener: AudinOperatorListener<K>): () => void;
    /**
     * List the phone numbers this account owns and may go online on / dial from.
     *
     * Fetches over REST using the SAME short-lived session token the WebSockets
     * use (obtained through `getToken`) — the Account API Key never enters the
     * browser. On a 401 the cached token is invalidated and the request is
     * retried ONCE with a fresh token; a second 401 throws an
     * {@link OperatorRequestError} with code `UNAUTHORIZED`. Other non-OK
     * responses throw with code `REQUEST_FAILED`.
     *
     * Use a returned number's `id` for {@link goOnline} and its `phoneNumber`
     * (E.164) as the `callerId` for {@link dial}.
     */
    listPhoneNumbers(): Promise<OperatorPhoneNumber[]>;
    private fetchPhoneNumbers;
    /**
     * Go online and start accepting inbound calls on `phoneNumberIds`. Connects
     * the presence channel (fetching a token via `getToken`) and announces
     * availability. Safe to call again to change the number set.
     */
    goOnline(phoneNumberIds: string[]): Promise<void>;
    /**
     * Go offline: drop availability, tear down any active call, and close the
     * presence channel (no auto-reconnect until `goOnline` again).
     */
    goOffline(): Promise<void>;
    /** Current presence channel state. */
    get state(): PresenceState;
    /** The current active/ringing call, if any. */
    get currentCall(): OperatorCall | null;
    /**
     * Switch the microphone constraints used to capture the operator's audio —
     * typically to pick a specific input device, e.g.
     * `setAudioConstraints({ deviceId: { exact: id }, echoCancellation: true })`.
     *
     * Takes effect from the NEXT call: a call already in progress keeps the
     * device its {@link AudioBridge} opened with (this does not re-open the
     * microphone mid-call). The new constraints are read when the next
     * `dial`/accepted-inbound opens its audio leg.
     */
    setAudioConstraints(constraints: MediaTrackConstraints): void;
    /**
     * Place an outbound call to `to` (E.164), presenting `options.callerId`
     * (which must be an active number your account owns). Resolves once the call
     * is accepted by the platform and the audio bridge is opening; rejects on
     * validation failure, a busy operator, or if the platform doesn't ack in
     * time.
     */
    dial(to: string, options: DialOptions): Promise<OperatorCall>;
    private handlePresenceMessage;
    private handleIncomingCall;
    private handleCallTaken;
    private handleCallAssigned;
    private handleOutboundStarted;
    private openAudioBridge;
    private onBridgeClosed;
    private makeCall;
    private endCallWithReason;
    private teardownActiveCall;
    private failPendingOutbound;
    private setPresenceState;
    private emitError;
    /** Public-facing emit wrapper (the base `emit` is protected). */
    private emitEvent;
}
/**
 * Normalise a base URL into a `ws(s)://host` origin with no trailing slash and
 * no path. Accepts `http(s)` or `ws(s)`; upgrades the scheme accordingly.
 */
export declare function toWsBase(coreUrl: string): string;
/**
 * Normalise a base URL into an `http(s)://host` origin with no trailing slash
 * and no path. Accepts `http(s)` or `ws(s)`; downgrades the WS scheme to the
 * matching HTTP scheme for REST calls.
 */
export declare function toHttpBase(coreUrl: string): string;
/** Error thrown by the SDK's REST helpers (e.g. {@link AudinOperator.listPhoneNumbers}). */
export declare class OperatorRequestError extends Error {
    /** Stable machine code: `UNAUTHORIZED` | `REQUEST_FAILED`. */
    readonly code: string;
    /** Original error / response context, if any. */
    readonly cause?: unknown;
    constructor(code: string, message: string, cause?: unknown);
}
