/// <reference types="node" resolution-mode="require"/>
import type { AudioFrame, Room } from '@livekit/rtc-node';
import type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';
import type { Context } from '@opentelemetry/api';
import type { ReadableStream } from 'node:stream/web';
import { type LLMModels, type STTModelString, type TTSModelString } from '../inference/index.js';
import type { FunctionCall, FunctionCallOutput } from '../llm/chat_context.js';
import { ChatContext, ChatMessage } from '../llm/chat_context.js';
import type { LLM, RealtimeModel, RealtimeModelError, ToolChoice } from '../llm/index.js';
import type { LLMError } from '../llm/llm.js';
import type { STT } from '../stt/index.js';
import type { STTError } from '../stt/stt.js';
import type { TTS, TTSError } from '../tts/tts.js';
import { type ResolvedSessionConnectOptions, type SessionConnectOptions } from '../types.js';
import type { VAD } from '../vad.js';
import type { Agent } from './agent.js';
import type { _TurnDetector } from './audio_recognition.js';
import { type AgentEvent, AgentSessionEventTypes, type AgentState, type AgentStateChangedEvent, type CloseEvent, type ConversationItemAddedEvent, type ErrorEvent, type FunctionToolsExecutedEvent, type MetricsCollectedEvent, type ShutdownReason, type SpeechCreatedEvent, type UserInputTranscribedEvent, type UserState, type UserStateChangedEvent } from './events.js';
import { AgentInput, AgentOutput } from './io.js';
import { RecorderIO } from './recorder_io/index.js';
import { type RoomInputOptions, type RoomOutputOptions } from './room_io/index.js';
import type { UnknownUserData } from './run_context.js';
import type { SpeechHandle } from './speech_handle.js';
import { RunResult } from './testing/run_result.js';
export interface VoiceOptions {
    allowInterruptions: boolean;
    discardAudioIfUninterruptible: boolean;
    minInterruptionDuration: number;
    minInterruptionWords: number;
    minEndpointingDelay: number;
    maxEndpointingDelay: number;
    maxToolSteps: number;
    preemptiveGeneration: boolean;
    userAwayTimeout?: number | null;
    useTtsAlignedTranscript: boolean;
}
export type TurnDetectionMode = 'stt' | 'vad' | 'realtime_llm' | 'manual' | _TurnDetector;
export type AgentSessionCallbacks = {
    [AgentSessionEventTypes.UserInputTranscribed]: (ev: UserInputTranscribedEvent) => void;
    [AgentSessionEventTypes.AgentStateChanged]: (ev: AgentStateChangedEvent) => void;
    [AgentSessionEventTypes.UserStateChanged]: (ev: UserStateChangedEvent) => void;
    [AgentSessionEventTypes.ConversationItemAdded]: (ev: ConversationItemAddedEvent) => void;
    [AgentSessionEventTypes.FunctionToolsExecuted]: (ev: FunctionToolsExecutedEvent) => void;
    [AgentSessionEventTypes.MetricsCollected]: (ev: MetricsCollectedEvent) => void;
    [AgentSessionEventTypes.SpeechCreated]: (ev: SpeechCreatedEvent) => void;
    [AgentSessionEventTypes.Error]: (ev: ErrorEvent) => void;
    [AgentSessionEventTypes.Close]: (ev: CloseEvent) => void;
};
export type AgentSessionOptions<UserData = UnknownUserData> = {
    turnDetection?: TurnDetectionMode;
    stt?: STT | STTModelString;
    vad?: VAD;
    llm?: LLM | RealtimeModel | LLMModels;
    tts?: TTS | TTSModelString;
    userData?: UserData;
    voiceOptions?: Partial<VoiceOptions>;
    connOptions?: SessionConnectOptions;
};
declare const AgentSession_base: new () => TypedEmitter<AgentSessionCallbacks>;
export declare class AgentSession<UserData = UnknownUserData> extends AgentSession_base {
    vad?: VAD;
    stt?: STT;
    llm?: LLM | RealtimeModel;
    tts?: TTS;
    turnDetection?: TurnDetectionMode;
    readonly options: VoiceOptions;
    private agent?;
    private activity?;
    private nextActivity?;
    private started;
    private userState;
    private roomIO?;
    private logger;
    private _chatCtx;
    private _userData;
    private _agentState;
    private _input;
    private _output;
    private closingTask;
    private userAwayTimer;
    private _connOptions;
    private llmErrorCounts;
    private ttsErrorCounts;
    private sessionSpan?;
    private userSpeakingSpan?;
    private agentSpeakingSpan?;
    /** @internal */
    _recorderIO?: RecorderIO;
    /** @internal */
    rootSpanContext?: Context;
    /** @internal */
    _recordedEvents: AgentEvent[];
    /** @internal */
    _enableRecording: boolean;
    /** @internal - Timestamp when the session started (milliseconds) */
    _startedAt?: number;
    /** @internal - Current run state for testing */
    _globalRunState?: RunResult;
    constructor(opts: AgentSessionOptions<UserData>);
    emit<K extends keyof AgentSessionCallbacks>(event: K, ...args: Parameters<AgentSessionCallbacks[K]>): boolean;
    get input(): AgentInput;
    get output(): AgentOutput;
    get userData(): UserData;
    get history(): ChatContext;
    /** Connection options for STT, LLM, and TTS. */
    get connOptions(): ResolvedSessionConnectOptions;
    get useTtsAlignedTranscript(): boolean;
    set userData(value: UserData);
    private _startImpl;
    start({ agent, room, inputOptions, outputOptions, record, }: {
        agent: Agent;
        room?: Room;
        inputOptions?: Partial<RoomInputOptions>;
        outputOptions?: Partial<RoomOutputOptions>;
        record?: boolean;
    }): Promise<void>;
    updateAgent(agent: Agent): void;
    commitUserTurn(): void;
    clearUserTurn(): void;
    say(text: string | ReadableStream<string>, options?: {
        audio?: ReadableStream<AudioFrame>;
        allowInterruptions?: boolean;
        addToChatCtx?: boolean;
    }): SpeechHandle;
    interrupt(): import("../utils.js").Future<void>;
    generateReply(options?: {
        userInput?: string;
        instructions?: string;
        toolChoice?: ToolChoice;
        allowInterruptions?: boolean;
    }): SpeechHandle;
    /**
     * Run a test with user input and return a result for assertions.
     *
     * This method is primarily used for testing agent behavior without
     * requiring a real room connection.
     *
     * @example
     * ```typescript
     * const result = await session.run({ userInput: 'Hello' });
     * result.expect.nextEvent().isMessage({ role: 'assistant' });
     * result.expect.noMoreEvents();
     * ```
     *
     * @param options - Run options including user input
     * @returns A RunResult that resolves when the agent finishes responding
     *
     * TODO: Add outputType parameter for typed outputs (parity with Python)
     */
    run(options: {
        userInput: string;
    }): RunResult;
    private updateActivity;
    get chatCtx(): ChatContext;
    get agentState(): AgentState;
    get currentAgent(): Agent;
    close(): Promise<void>;
    shutdown(options?: {
        drain?: boolean;
        reason?: ShutdownReason;
    }): void;
    /** @internal */
    _closeSoon({ reason, drain, error, }: {
        reason: ShutdownReason;
        drain?: boolean;
        error?: RealtimeModelError | STTError | TTSError | LLMError | null;
    }): void;
    /** @internal */
    _onError(error: RealtimeModelError | STTError | TTSError | LLMError): void;
    /** @internal */
    _conversationItemAdded(item: ChatMessage): void;
    /** @internal */
    _toolItemsAdded(items: (FunctionCall | FunctionCallOutput)[]): void;
    /** @internal */
    _updateAgentState(state: AgentState, options?: {
        startTime?: number;
        otelContext?: Context;
    }): void;
    /** @internal */
    _updateUserState(state: UserState, lastSpeakingTime?: number): void;
    private onAudioInputChanged;
    private onAudioOutputChanged;
    private onTextOutputChanged;
    private _setUserAwayTimer;
    private _cancelUserAwayTimer;
    private _onUserInputTranscribed;
    private closeImpl;
    private closeImplInner;
}
export {};
//# sourceMappingURL=agent_session.d.ts.map