import type { SIPOutboundConfig } from '@livekit/protocol';
import type { LLMModels, STTModelString, TTSModelString } from '../inference/index.js';
import type { ChatContext, LLM, RealtimeModel, ToolContextEntry } from '../llm/index.js';
import type { STT } from '../stt/index.js';
import type { TTS } from '../tts/index.js';
import type { VAD } from '../vad.js';
import { AgentTask } from '../voice/agent.js';
import { AgentSession, type TurnDetectionMode } from '../voice/agent_session.js';
import { type AudioConfig, type AudioSourceType } from '../voice/background_audio.js';
import type { SpeechHandle } from '../voice/speech_handle.js';
import type { InstructionParts } from './utils.js';
export interface WarmTransferResult {
    humanAgentIdentity: string;
}
/**
 * Exact text or a callback that starts speech in the consultation session.
 *
 * @public
 */
export type WarmTransferSpeech = string | ((session: AgentSession) => SpeechHandle);
export interface WarmTransferTaskOptions {
    /**
     * Signal for application cancellation, such as a consult deadline or application shutdown.
     *
     * Do not abort this signal when the caller disconnects. The task handles caller disconnects so
     * it can play `callerHangupInstruction` before it ends an answered consultation.
     *
     * A successful participant move wins if it completes after the signal aborts. The task stops
     * waiting for a pending SIP request but cannot cancel it.
     */
    abortSignal?: AbortSignal;
    /** The phone number or SIP URI to dial for the human agent. */
    sipCallTo?: string;
    /**
     * ID of a pre-configured LiveKit SIP outbound trunk used to originate the call.
     * Falls back to the `LIVEKIT_SIP_OUTBOUND_TRUNK` environment variable when not provided.
     */
    sipTrunkId?: string | null;
    /** Low-level SIP connection config for originating calls through a custom SIP domain. */
    sipConnection?: SIPOutboundConfig;
    /** Optional SIP From number. Falls back to `LIVEKIT_SIP_NUMBER`. */
    sipNumber?: string;
    /** Headers to include on the outbound SIP call. */
    sipHeaders?: Record<string, string>;
    /**
     * DTMF tones to send once the human agent's call is answered, e.g. to dial an extension or
     * navigate an IVR menu (`'1234#'`). Insert `w` characters to pause ~0.5s each before/between
     * digits (`'wwww1234#'` waits ~2s, useful when the destination plays a greeting before
     * accepting input).
     */
    dtmf?: string | null;
    /**
     * How long to wait, in milliseconds, for the human agent to answer before giving up. The
     * underlying SIP API only supports whole-second granularity, so the value is rounded to the
     * nearest second.
     */
    ringingTimeout?: number | null;
    /**
     * Name of the room used to dial and brief the human agent. Defaults to
     * `${callerRoom.name}-human-agent`.
     *
     * Set this to control the briefing room's configuration: pre-create a room
     * under this name (e.g. with `RoomServiceClient.createRoom` and an `egress`
     * request to record the transfer leg) before running the task, and the
     * transfer agent joins the pre-configured room instead of implicitly
     * creating one with project defaults.
     *
     * The room is deleted when the transfer completes, fails, or is cancelled
     * (the same lifecycle as the default room), which also ends any egress
     * attached to it. Must differ from the caller room's name.
     */
    roomName?: string;
    /** Audio played to the caller while they are on hold during the transfer. */
    holdAudio?: AudioSourceType | AudioConfig | AudioConfig[] | null;
    /**
     * Speech started after the outbound SIP call is answered. A string is spoken with
     * `session.say()`. A callback runs once after answer with the consultation session and must
     * return a speech handle. Omit this option to let the destination speak first. The answer signal
     * does not distinguish a person from voicemail or an IVR, so an enabled greeting can overlap
     * automated audio.
     */
    greetingSpeech?: WarmTransferSpeech;
    /**
     * Speech played before ending the human agent's call when the caller hangs up after the human
     * agent answers. A string is spoken with `session.say()` and requires a TTS model. For sessions
     * without TTS, use a callback that returns `session.say(text, { audio })` with prerecorded audio.
     * The callback runs only after the caller hangs up, and the task awaits its returned handle.
     * This option takes precedence over `callerHangupInstruction`.
     */
    callerHangupSpeech?: WarmTransferSpeech;
    /**
     * Instructions used to generate the reply spoken to the human agent before their call is
     * ended when the caller hangs up mid-transfer (after the human agent answered but before
     * the merge). Falls back to a built-in instruction when not provided.
     *
     * @deprecated Use `callerHangupSpeech`. Return `session.generateReply()` from its callback to
     * keep generated speech.
     */
    callerHangupInstruction?: string | null;
    /**
     * Instructions for the human agent briefing. Pass a full string to replace the built-in prompt
     * entirely, or {@link InstructionParts} to override individual sections (e.g. `persona`) while
     * keeping the built-in template and auto-formatted conversation history.
     */
    instructions?: InstructionParts | string;
    chatCtx?: ChatContext;
    turnDetection?: TurnDetectionMode | null;
    tools?: readonly ToolContextEntry[];
    stt?: STT | STTModelString | null;
    vad?: VAD | null;
    llm?: LLM | RealtimeModel | LLMModels | null;
    tts?: TTS | TTSModelString | null;
    allowInterruptions?: boolean;
}
/**
 * Build a warm-transfer {@link AgentTask} that dials a human agent over SIP, briefs them
 * in a private room, and (on confirmation) merges them into the caller room.
 *
 * If the caller hangs up before the merge — including while the human agent's phone is
 * still ringing — the transfer is cancelled: the pending dial is aborted, the human agent
 * room is torn down (ending the SIP call), and the task completes with a {@link ToolError}.
 * A human agent who already answered is told the caller left using `callerHangupSpeech`, or a
 * reply generated from the deprecated `callerHangupInstruction`, before their call is ended.
 *
 * This is the functional core; {@link WarmTransferTask} is a thin class wrapper over it.
 */
export declare function createWarmTransferTask({ abortSignal, sipCallTo, sipTrunkId: rawSipTrunkId, sipConnection, sipNumber, sipHeaders, dtmf, ringingTimeout, roomName: rawRoomName, holdAudio, greetingSpeech, callerHangupSpeech, callerHangupInstruction, instructions, chatCtx, turnDetection, tools, stt, vad, llm, tts, allowInterruptions, }?: WarmTransferTaskOptions): AgentTask<WarmTransferResult>;
/**
 * Class wrapper around {@link createWarmTransferTask}, preserving the
 * `new WarmTransferTask(options).run()` API. It composes the functional task and
 * delegates `run()` to it.
 */
export declare class WarmTransferTask extends AgentTask<WarmTransferResult> {
    #private;
    constructor(options?: WarmTransferTaskOptions);
    run(): Promise<WarmTransferResult>;
}
/**
 * Resolve the name of the room used to dial and brief the human agent.
 *
 * Exported for testing; not re-exported from the package index.
 */
export declare function resolveHumanAgentRoomName(callerRoomName: string, override?: string): string;
/** @internal */
export declare function createWarmTransferSpeech(session: AgentSession, speech: WarmTransferSpeech | undefined, sayOptions?: Parameters<AgentSession['say']>[1]): SpeechHandle | undefined;
/** @internal */
export declare function createCallerHangupSpeech(session: AgentSession, callerHangupSpeech: WarmTransferSpeech | undefined, callerHangupInstruction: string | null | undefined): SpeechHandle;
//# sourceMappingURL=warm_transfer.d.ts.map