import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import * as THREE from 'three';
import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js';
import Emittery from 'emittery';
import * as lodash from 'lodash';

/**
 * 事件枚举
 * 定义 JSSDK 中所有可触发的事件类型
 */
declare enum EmitEvent {
  // ==================== Human 对象生命周期事件 ====================
  
  /** Human 对象加载完成，可以开始使用 */
  HUMAN_READY = 'human.ready',
  
  /** Human 对象发生错误 */
  HUMAN_ERROR = 'human.error',
  
  /** Human 对象触发指令动作 */
  HUMAN_ACTION_PENDING = 'human.action.pending',
  
  /** Human 对象加载进度更新 */
  HUMAN_LOAD_PROGRESS = 'human.load.progress',
  
  /** 核心模型包加载完成 */
  CORE_BUNDLES_LOADED = 'core.bundles.loaded',
  
  // ==================== 音频播放事件 ====================
  
  /** 音频开始播放 */
  AUDIO_PLAY = 'audio.play',
  
  /** 音频暂停播放 */
  AUDIO_PAUSE = 'audio.pause',
  
  /** 音频静音/取消静音 */
  AUDIO_MUTE = 'audio.mute',
  
  // ==================== 录音相关事件 ====================
  
  /** 录音器消息 */
  RECORDER_MESSAGE = 'recorder.message',
  
  /** 录音开始 */
  RECORDER_START = 'recorder.start',
  
  /** 录音结束 */
  RECORDER_STOP = 'recorder.stop',
  
  /** 发送录音数据到 ASR 服务 */
  RECORDER_SENDING = 'recorder.sending',
  
  // ==================== 语音交互事件 ====================
  
  /** 语音交互进入睡眠模式 */
  VOICE_SLEEP = 'voice.sleep',
  
  /** 语音交互被唤醒 */
  VOICE_WAKE = 'voice.wake',
  
  /** 语音交互被打断 */
  VOICE_INTERRUPT = 'voice.interrupt',

  /** TTS 播放期间用户打断（Barge-in） */
  VOICE_BARGE_IN = 'voice.barge_in',

  /** 语音转文本结果 */
  VOICE2TEXT = 'voice2text',
  
  /** 唤醒状态下开始录音 */
  WAKE_RECORDER_START = 'wake.record.start',
  
  /** 唤醒状态下结束录音 */
  WAKE_RECORDER_STOP = 'wake.record.stop',
  
  // ==================== 语音交互模式事件 ====================
  
  /** 语音交互模式已开启 */
  VOICE_INTERACTION_OPENED = 'voice.interaction.opened',
  
  /** 语音交互模式已关闭 */
  VOICE_INTERACTION_CLOSED = 'voice.interaction.closed',
  
  /** 语音交互被唤醒（检测到唤醒词） */
  VOICE_INTERACTION_WAKEUP = 'voice.interaction.wakeup',
  
  /** 语音交互进入休眠（检测到退出词或超时） */
  VOICE_INTERACTION_SLEEP = 'voice.interaction.sleep',

  /** 唤醒确认语播报 */
  VOICE_INTERACTION_WAKE_CONFIRM = 'voice.interaction.wake.confirm',

  /** 优雅退出提示语播报 */
  VOICE_INTERACTION_EXIT_PROMPT = 'voice.interaction.exit.prompt',

  /** 退出提示语播完后进入等待态（显示推荐问题，等待用户再次唤醒） */
  VOICE_INTERACTION_POST_EXIT_IDLE = 'voice.interaction.post_exit_idle',

  /** 语音交互被打断（检测到打断词） */
  VOICE_INTERACTION_INTERRUPT = 'voice.interaction.interrupt',

  /** 显示打断提示（SPEAKING 状态 2 秒后） */
  VOICE_INTERRUPT_HINT_SHOW = 'voice.interrupt.hint.show',

  /** 隐藏打断提示 */
  VOICE_INTERRUPT_HINT_HIDE = 'voice.interrupt.hint.hide',

  /** 语音打断成功（用户说出打断词） */
  VOICE_INTERRUPTED = 'voice.interrupted',

  /** 开始采集音频 */
  VOICE_INTERACTION_AUDIO_START = 'voice.interaction.audio.start',
  
  /** 停止采集音频 */
  VOICE_INTERACTION_AUDIO_STOP = 'voice.interaction.audio.stop',
  
  /** 语音播放开始 */
  VOICE_INTERACTION_PLAY_START = 'voice.interaction.play.start',
  
  /** 语音播放结束 */
  VOICE_INTERACTION_PLAY_END = 'voice.interaction.play.end',
  
  /** WebRTC 连接状态变化 */
  VOICE_INTERACTION_WEBRTC_STATE = 'voice.interaction.webrtc.state',

  /** WebRTC TTS 音频开始播放（用于回声抑制） */
  WEBRTC_TTS_PLAY_START = 'webrtc.tts.play.start',

  /** WebRTC TTS 音频结束播放（用于回声抑制） */
  WEBRTC_TTS_PLAY_END = 'webrtc.tts.play.end',

  // ==================== 对话和 TTS 事件 ====================
  
  /** 对话消息的 BlendShapes 动画开始播放 */
  CHAT_MESSAGE_BS_PLAY_START = 'chat.message.bs.play.start',
  
  /** 对话消息的 BlendShapes 动画结束播放 */
  CHAT_MESSAGE_BS_PLAY_END = 'chat.message.bs.play.end',
  
  // ==================== Agent 工具交互事件 ====================

  /** 收到服务端工具执行结果 (CMD 1040): quiz card, reward animation, etc. */
  TOOL_RESULT = 'tool.result',

  // ==================== Gateway 服务事件 ====================

  /** Gateway WebSocket 连接成功 */
  GATEWAY_CONNECTED = 'gateway.connected',
  
  /** Gateway WebSocket 断开连接 */
  GATEWAY_DISCONNECTED = 'gateway.disconnected',
  
  /** Gateway WebSocket 正在重连 */
  GATEWAY_RECONNECTING = 'gateway.reconnecting',
  
  /** Gateway 接收到消息 */
  GATEWAY_MESSAGE = 'gateway.message',
  
  /** Gateway 发生错误 */
  GATEWAY_ERROR = 'gateway.error',

  /** Gateway 主动推送会话状态（CMD 1030）。例如播完退出语后推送 SLEEPING，reason=graceful_exit */
  GATEWAY_STATE_PUSH = 'gateway.state.push',
  
  // ==================== 摄像头相关事件 ====================
  
  /** 摄像头人体检测结果 */
  CAMERA_PERSON_TEST_RESULT = 'camera.person.test.result',
  
  /** 摄像头人脸识别结果 */
  CAMERA_FACE_RECOGNITION_RESULT = 'camera.face.recognition.result',

  /** 摄像头表情检测：检测到微笑（边沿事件，受 cooldown 控制） */
  EXPRESSION_SMILE_DETECTED = 'expression.smile.detected',

  /** 摄像头表情检测：微笑状态变化（状态流，smileCount>0 时每秒 heartbeat） */
  EXPRESSION_SMILE_STATE_CHANGED = 'expression.smile.state_changed',

  // ==================== 渲染相关事件 ====================
  
  /** 渲染服务初始化完成 */
  RENDER_READY = 'render.ready',
  
  /** 渲染服务发生错误 */
  RENDER_ERROR = 'render.error',
  
  /** 模型加载进度更新 */
  MODEL_LOAD_PROGRESS = 'model.load.progress',
  
  /** 模型加载完成 */
  MODEL_LOADED = 'model.loaded',
  
  /** 模型加载失败 */
  MODEL_LOAD_FAILED = 'model.load.failed',
  
  /** 动画播放开始 */
  ANIMATION_START = 'animation.start',
  
  /** 动画播放结束 */
  ANIMATION_END = 'animation.end',

  ERROR = 'error'
}

/**
 * API 相关类型定义
 * @module types/api
 */

/**
 * 通用响应结果
 * 所有 API 接口的标准响应格式
 * 
 * @template T 响应数据的类型
 * 
 * @example
 * ```typescript
 * const result: Result<string> = {
 *   code: 0,
 *   msg: 'success',
 *   data: 'Hello World'
 * }
 * ```
 */
interface Result$1<T = any> {
  /** 
   * 状态码
   * - `0`: 成功
   * - 其他值: 失败
   */
  code: number;
  
  /** 
   * 响应消息
   * 描述请求的结果或错误信息
   */
  msg: string;
  
  /** 
   * 响应数据
   * 具体的业务数据
   */
  data: T;
}

/**
 * 消息角色
 * 用于标识对话中的发言者
 */
type MessageRole = 
  /** 用户 */
  | 'user' 
  /** AI 助手 */
  | 'assistant' 
  /** 系统 */
  | 'system';

/**
 * 对话消息
 * 表示对话中的一条消息
 * 
 * @example
 * ```typescript
 * const message: Message = {
 *   role: 'user',
 *   content: '你好，请介绍一下自己'
 * }
 * ```
 */
interface Message {
  /** 
   * 消息角色
   * 标识这条消息的发言者
   */
  role: MessageRole;
  
  /** 
   * 消息内容
   * 具体的文本内容
   */
  content: string;
}

/**
 * TTS 音色
 * 文本转语音时使用的声音类型
 */
type TTSRole = 
  /** 女声 */
  | 'woman' 
  /** 男声 */
  | 'man' 
  /** 晓晓（女声） */
  | 'xiaoxiao' 
  /** 云霄（男声） */
  | 'yunxiao' 
  /** 云皓（男声） */
  | 'yunhao';

/**
 * TTS 模型
 * 文本转语音使用的模型类型
 */
type TTSModel = 
  /** GPT-SoVITS 模型 */
  | 'gpt-sovits' 
  /** 讯飞模型 */
  | 'xunfei' 
  /** PaddleSpeech 模型 */
  | 'paddle' 
  /** PaddleSpeech v2 模型 */
  | 'paddle2' 
  /** Azure 模型 */
  | 'azure';

/**
 * TTS 口型类型
 * BlendShapes 数据的格式类型
 */
type TTSViseme = 
  /** Azure 格式 */
  | 'azure' 
  /** Oculus OVR 格式 */
  | 'ovr' 
  /** Audio2Face 格式 */
  | 'a2f' 
  /** 全特格式 */
  | 'qt' 
  /** 无口型数据 */
  | 'none' 
  /** Audio2Face 3D 格式 */
  | 'a2f3d';

/**
 * 对话响应模式
 */
type ChatResponseMode = 
  /** 流式响应，实时返回结果 */
  | 'streaming' 
  /** 阻塞式响应，等待完整结果 */
  | 'blocking';

/**
 * 对话文件
 * 用于在对话中上传图片等文件
 * 
 * @example
 * ```typescript
 * const file: ChatFile = {
 *   type: 'image',
 *   transfer_method: 'remote_url',
 *   url: 'https://example.com/image.jpg'
 * }
 * ```
 */
interface ChatFile {
  /** 
   * 文件类型
   * 目前仅支持图片
   */
  type: 'image';
  
  /** 
   * 传输方式
   * - `remote_url`: 远程网络地址
   * - `local_file`: 本地文件
   */
  transfer_method: 'remote_url' | 'local_file';
  
  /** 
   * 文件地址
   * 图片的 URL 或本地路径
   */
  url: string;
}

/**
 * 对话参数
 * 用于 askStream 方法的参数配置
 * 
 * @example
 * ```typescript
 * // 单轮对话
 * const params: AskParams = {
 *   message: [
 *     { role: 'user', content: '你好' }
 *   ]
 * }
 * 
 * // 多轮对话（带上下文）
 * const params: AskParams = {
 *   message: [
 *     { role: 'user', content: '今天天气怎么样？' },
 *     { role: 'assistant', content: '今天天气晴朗。' },
 *     { role: 'user', content: '那适合户外运动吗？' }
 *   ],
 *   conversation_id: 'conv-123'
 * }
 * 
 * // 带图片的对话
 * const params: AskParams = {
 *   message: [
 *     { role: 'user', content: '这是什么？' }
 *   ],
 *   files: [
 *     {
 *       type: 'image',
 *       transfer_method: 'remote_url',
 *       url: 'https://example.com/image.jpg'
 *     }
 *   ]
 * }
 * ```
 */
interface AskParams {
  /** 
   * 请求 ID
   * 可选的唯一标识符，用于追踪请求
   * @example 'req-123456'
   */
  reqId?: string;
  
  /** 
   * 消息列表
   * 对话的消息历史，包含用户和助手的消息
   * 支持多轮对话，按时间顺序排列
   */
  message: Message[];
  
  /** 
   * 会话 ID
   * 用于标识同一个对话会话，保持上下文连贯性
   * @example 'conv-123456'
   */
  conversation_id?: string;
  
  /** 
   * 响应模式
   * - `streaming`: 流式响应（默认），实时返回结果
   * - `blocking`: 阻塞式响应，等待完整结果
   * @default 'streaming'
   */
  response_mode?: ChatResponseMode;
  
  /** 
   * 文件列表
   * 可选的文件附件，如图片
   */
  files?: ChatFile[];
  
  /** 
   * 命令类型
   * 用于特殊命令处理
   * @internal
   */
  commandType?: string;
  
  /** 
   * 输入参数
   * 额外的输入参数
   * @internal
   */
  inputs?: Record<string, any>;
}

/**
 * 对话消息参数（用于旧版 API）
 * @deprecated 请使用 AskParams
 */
interface ChatMessageParams extends Omit<AskParams, 'reqId'> {
  /** 语言 */
  language?: string;
  /** 查询文本（从 message 中提取） */
  query?: string;
}

/**
 * 对话消息事件
 */
interface ChatMessage$1 {
  /** 事件类型 */
  event: 'message' | 'message_end' | 'error';
  /** 会话 ID */
  conversation_id: string;
  /** 消息 ID */
  message_id: string;
  /** 创建时间 */
  created_at: number;
  /** 任务 ID */
  task_id: string;
  /** ID */
  id: string;
  /** 回答内容 */
  answer: string;
  /** 来源变量选择器 */
  from_variable_selector?: string;
  /** 消息内容 */
  message?: string;
}

/**
 * 播放信息
 */
interface PlayInfo {
  /** BlendShapes 数据 */
  shapes: number[][];
  /** 音频链接 */
  url: string;
  /** 音频时长（秒） */
  duration: number;
  /** 文本内容 */
  content: string;
}

/**
 * 流式音频播放信息
 */
interface StreamAudioPlayInfo {
  /** BlendShapes 数据 */
  shapes: number[][];
  /** 音频数据 */
  audios: ArrayBuffer[];
  /** 音频时长（秒） */
  duration: number;
  /** 文本内容 */
  content: string;
  /** 音频采样率 */
  rate: number;
}

/**
 * 对话错误信息
 */
interface AskError {
  /** 文本内容 */
  content: string;
  /** 错误消息 */
  errorMessage: string;
}

/**
 * 对话响应
 */
interface AskResponse {
  /** 请求 ID */
  reqId: string;
  /** 播放信息列表 */
  playInfos: PlayInfo[];
  /** 错误信息列表 */
  errorInfos: AskError[];
}

/**
 * 流式对话响应
 */
interface AskStreamResponse {
  /** 请求 ID */
  reqId: string;
  /** 播放信息列表 */
  playInfos: StreamAudioPlayInfo[];
  /** 错误信息列表 */
  errorInfos: AskError[];
}

/**
 * TTS 参数
 */
interface TTSParams$1 {
  /** 音色 */
  role?: TTSRole;
  /** 内容 */
  content: string;
  /** 语速，默认: 1 */
  speed?: number;
  /** 模型，默认: gpt-sovits */
  model?: TTSModel;
  /** 口型，默认: a2f */
  viseme?: TTSViseme;
  /** 是否开启平滑 [0: 关闭，1: 开启]，默认开启 */
  smooth_method?: number;
  /** 平滑值：[1~10]，默认5 */
  smooth_iterations?: number;
}

/**
 * TTS 响应
 */
interface TTSResponse$1 {
  /** 音频 URL */
  url: string;
  /** 音频时长（秒） */
  duration: number;
  /** BlendShapes 数据 */
  blend_shapes: number[] | number[][];
  /** 语音文本 */
  content: string;
}

/**
 * 语音识别结果
 */
interface Voice2TextResult {
  /** 是否为最终结果 */
  is_final: boolean;
  /** 识别文本 */
  text: string;
  /** 音频文件名 */
  wav_name?: string;
  /** 模型 */
  mode?: string;
  /** 置信度 */
  confidence?: number;
}

/**
 * 数字人信息
 */
interface CharacterInfo {
  id: string;
  name: string;
  description: string;
  language: string;
  token: string;
  timbre?: any;
  animations?: any[];
  aposes?: any[];
  scene?: any;
  configuration?: any;
  pronunciations?: any[];
  renderings?: string[];
  animationEnabled?: string;
}

/**
 * 数字人模型文件
 */
interface CharacterModel {
  id: string;
  name: string;
  enabled: boolean;
  code: string;
  bundle: string;
  type: 'apose' | 'animation' | 'animation_system';
}

/**
 * 录音权限结果
 */
interface RecorderPermission {
  /** 状态码 */
  code?: string;
  /** 消息 */
  msg?: string;
  /** 用户是否拒绝权限 */
  isUserNotAllow?: boolean;
}

/**
 * 对话回调函数
 */
type AskCallback = (result: Result$1<ChatMessage$1>) => void;

/**
 * 播报回调函数
 */
type SpeakCallback = (result: Result$1<TTSResponse$1>) => void;

/**
 * 语音识别回调函数
 */
type Voice2TextCallback = (result: Voice2TextResult) => void;

/**
 * Gateway 服务相关类型定义
 */



/**
 * Gateway 配置
 */
type IOSAudioMode = 'baseline' | 'aec' | 'aec_full';

interface GatewayConfig$1 {
  /** Gateway WebSocket 地址 */
  url: string;
  /** 授权 Token */
  token: string;
  /** 麦克风采集档位：standard 保守，asr_priority 更偏 ASR 识别 */
  audioProfile?: 'standard' | 'asr_priority';
  /** iOS 音频实验模式：baseline 保持现状，aec/aec_full 用于验证浏览器 AEC */
  iosAudioMode?: IOSAudioMode;
  /** 自动重连 */
  autoReconnect?: boolean;
  /** 重连间隔（毫秒） */
  reconnectInterval?: number;
  /** 最大重连次数 */
  maxReconnectAttempts?: number;
  /** 心跳间隔（毫秒） */
  heartbeatInterval?: number;
}

/**
 * Gateway 消息类型
 */
type GatewayMessageType = 'chat' | 'tts' | 'asr' | 'heartbeat' | 'error';

/**
 * Gateway 请求基类
 */
interface GatewayRequestBase {
  /** 消息类型 */
  type: GatewayMessageType;
  /** 请求 ID */
  requestId: string;
  /** 时间戳 */
  timestamp?: number;
}

/**
 * Gateway 响应基类
 */
interface GatewayResponseBase {
  /** 消息类型 */
  type: GatewayMessageType;
  /** 事件名称 */
  event: string;
  /** 请求 ID */
  requestId?: string;
  /** 时间戳 */
  timestamp?: number;
}

/**
 * LLM 对话请求数据
 */
interface ChatRequestData {
  /** 消息列表 */
  message: Message[];
  /** 会话 ID */
  conversationId?: string;
  /** 模型 */
  model?: string;
  /** 文件列表 */
  files?: ChatFile[];
  /** 输入参数 */
  inputs?: Record<string, any>;
  /** 是否流式 */
  stream?: boolean;
}

/**
 * LLM 对话请求
 */
interface ChatRequest extends GatewayRequestBase {
  type: 'chat';
  data: ChatRequestData;
}

/**
 * LLM 对话响应数据
 */
interface ChatResponseData {
  /** 事件类型 */
  event: 'message' | 'message_end' | 'error';
  /** 会话 ID */
  conversationId: string;
  /** 消息 ID */
  messageId: string;
  /** 回答内容 */
  answer: string;
  /** 错误消息 */
  errorMessage?: string;
}

/**
 * LLM 对话响应
 */
interface ChatResponse extends GatewayResponseBase {
  type: 'chat';
  data: ChatResponseData;
}

/**
 * TTS 请求数据
 */
interface TTSRequestData extends TTSParams$1 {
  /** 文本内容 */
  content: string;
}

/**
 * TTS 请求
 */
interface TTSRequest extends GatewayRequestBase {
  type: 'tts';
  data: TTSRequestData;
}

/**
 * TTS 响应数据
 */
interface TTSResponseData {
  /** 事件类型 */
  event: 'audio' | 'audio_end' | 'error';
  /** 音频数据（Base64 或 ArrayBuffer） */
  audio?: ArrayBuffer | string;
  /** BlendShapes 数据 */
  blendShapes?: number[][];
  /** 音频时长（秒） */
  duration?: number;
  /** 采样率 */
  sampleRate?: number;
  /** 错误消息 */
  errorMessage?: string;
}

/**
 * TTS 响应
 */
interface TTSResponse extends GatewayResponseBase {
  type: 'tts';
  data: TTSResponseData;
}

/**
 * ASR 请求数据
 */
interface ASRRequestData {
  /** 音频数据 */
  audio: ArrayBuffer;
  /** 采样率 */
  sampleRate: number;
  /** 语言 */
  language?: string;
  /** 是否为最后一帧 */
  isLast?: boolean;
}

/**
 * ASR 请求
 */
interface ASRRequest extends GatewayRequestBase {
  type: 'asr';
  data: ASRRequestData;
}

/**
 * ASR 响应数据
 */
interface ASRResponseData {
  /** 事件类型 */
  event: 'text' | 'text_end' | 'error';
  /** 识别文本 */
  text: string;
  /** 是否为最终结果 */
  isFinal: boolean;
  /** 置信度 */
  confidence?: number;
  /** 错误消息 */
  errorMessage?: string;
}

/**
 * ASR 响应
 */
interface ASRResponse extends GatewayResponseBase {
  type: 'asr';
  data: ASRResponseData;
}

/**
 * 心跳请求
 */
interface HeartbeatRequest extends GatewayRequestBase {
  type: 'heartbeat';
  data: {
    ping: string;
  };
}

/**
 * 心跳响应
 */
interface HeartbeatResponse extends GatewayResponseBase {
  type: 'heartbeat';
  data: {
    pong: string;
  };
}

/**
 * 错误响应
 */
interface ErrorResponse extends GatewayResponseBase {
  type: 'error';
  data: {
    code: string | number;
    message: string;
    details?: any;
  };
}

/**
 * Gateway 请求联合类型
 */
type GatewayRequest =
  | ChatRequest
  | TTSRequest
  | ASRRequest
  | HeartbeatRequest;

/**
 * Gateway 响应联合类型
 */
type GatewayResponse =
  | ChatResponse
  | TTSResponse
  | ASRResponse
  | HeartbeatResponse
  | ErrorResponse;

/**
 * WebSocket 连接状态
 */
declare enum WebSocketState {
  CONNECTING = 0,
  OPEN = 1,
  CLOSING = 2,
  CLOSED = 3,
}

/**
 * 通用类型定义
 */

/**
 * Human 实例状态
 */
type Status = 'init' | 'ready' | 'prepare2play' | 'playing';

/**
 * 结果类型
 */
interface Result<T = any> {
  code: number;
  msg: string;
  data: T;
}

/**
 * 3D 模型相关类型定义
 * Three.js 相关类型和数字人模型配置
 */



type UUID = string;
type ColorHex = number;

type Vec2 = [number, number];
type Vec3 = [number, number, number];
type Vec4 = [number, number, number, number];
type Mat4 = number[]; // length 16

// 类型别名
type XYZ = Vec3;
type Matrix4 = Mat4;
type TCamera = PerspectiveCamera | OrthographicCamera;

/* ===== Root ===== */

interface ThreeJSON<T> {
  metadata?: {
    version: number;
    type:
      | "Object"
      | "Scene"
      | "Geometry"
      | "Material"
      | "BufferGeometry"
      | "Animation";
    generator: string;
  };

  object?: T;          // 主对象树（通常是 Scene / Object3D）
  geometries?: Geometry[];    // 资源池
  materials?: Material[];
  textures?: Texture[];
  images?: Image[];
  animations?: AnimationClip[];
  
  // OrbitControls specific properties
  useOrbitControl?: boolean;
  enableZoom?: boolean;
  enablePan?: boolean;
  minPolarAngle?: number;
  maxPolarAngle?: number;
  minAzimuthAngle?: number;
  maxAzimuthAngle?: number;
  minDistance?: number;
  maxDistance?: number;
  target?: number[];

  // 某些版本还会出现 fonts/shapes/nodes 等自定义扩展：
  [ext: string]: unknown;
}

/* ===== Object3D 基类 ===== */

interface Object3DBase {
  uuid: UUID;
  type: string;          // e.g. "Scene" | "Mesh" | "PerspectiveCamera" | "PointLight" | ...
  name?: string;

  // 变换
  matrix?: Mat4;         // 若存在，position/rotation/quaternion/scale 可能不会同时写出
  position?: Vec3;
  rotation?: Vec3;       // Euler (XYZ, radians)
  quaternion?: Vec4;
  scale?: Vec3;
  up?: Vec3;

  // 状态
  visible?: boolean;
  castShadow?: boolean;
  receiveShadow?: boolean;
  frustumCulled?: boolean;
  renderOrder?: number;
  layers?: number;

  userData?: Record<string, unknown>;

  children?: Object3D[]; // 层级
}

/* ===== 具体 Object 类型 ===== */

// ---------- Scene ----------
interface Scene extends Object3DBase {
  type: "Scene";
  background?: ColorHex | UUID | null; // 颜色或纹理/立方体纹理 uuid
  environment?: UUID | null;           // 环境贴图 uuid
  fog?: Fog | null;                // Fog / FogExp2
}

// ---------- Cameras ----------
interface Camera extends Object3DBase {
  type:
    | "PerspectiveCamera"
    | "OrthographicCamera"
    | "ArrayCamera"
    | "StereoCamera"; // 少见;通常只会导出前两者
  zoom?: number;
  near?: number;
  far?: number;
  focus?: number;
  fov?: number;        // 视场角
  filmGauge?: number;   // 透视相机可用
  filmOffset?: number;  // 透视相机可用
}

interface PerspectiveCamera extends Camera {
  type: "PerspectiveCamera";
  fov: number;
  // aspect 通常可选（可由渲染器设置），导出里不一定包含
  aspect?: number;
}

interface OrthographicCamera extends Camera {
  type: "OrthographicCamera";
  left: number;
  right: number;
  top: number;
  bottom: number;
}

// ---------- Lights ----------
interface Light extends Object3DBase {
  type:
    | "AmbientLight"
    | "HemisphereLight"
    | "DirectionalLight"
    | "PointLight"
    | "SpotLight"
    | "RectAreaLight";
  color?: ColorHex;
  intensity?: number;
}

interface AmbientLight extends Light {
  type: "AmbientLight";
}

interface HemisphereLight extends Light {
  type: "HemisphereLight";
  groundColor?: ColorHex;
  skyColor?: ColorHex;
}

interface DirectionalLight extends Light {
  type: "DirectionalLight";
  shadow?: LightShadow;
  // 目标通常以 Object3D 形式作为 child 一并导出，也可能出现 target uuid：
  target?: UUID;
}

interface PointLight extends Light {
  type: "PointLight";
  distance?: number;
  decay?: number;
  shadow?: LightShadow;
}

interface SpotLight extends Light {
  type: "SpotLight";
  distance?: number;
  angle?: number;
  penumbra?: number;
  decay?: number;
  shadow?: LightShadow;
  target?: UUID;
}

interface RectAreaLight extends Light {
  type: "RectAreaLight";
  width: number;
  height: number;
}

// 阴影
interface LightShadow {
  camera?: {
    type?: string; // "PerspectiveCamera" | "OrthographicCamera"
    near?: number;
    far?: number;
    fov?: number;      // 透视
    left?: number;     // 正交
    right?: number;
    top?: number;
    bottom?: number;
  };
  bias?: number;
  normalBias?: number;
  radius?: number;
  mapSize?: [number, number];
  autoUpdate?: boolean;
  needsUpdate?: boolean;
}

// ---------- Mesh / Line / Points / Sprite / Group / Bone ----------
interface Mesh extends Object3DBase {
  type: "Mesh" | "InstancedMesh" | "SkinnedMesh";
  geometry?: UUID;                 // 引用几何体
  material?: UUID | UUID[];        // 引用材质
  drawMode?: number;               // e.g. TrianglesDrawMode / TriangleStripDrawMode
  morphTargetInfluences?: number[];
  morphTargetDictionary?: Record<string, number>;
  // SkinnedMesh 专属
  bindMode?: "attached" | "detached" | string;
  bindMatrix?: Mat4;
  bindMatrixInverse?: Mat4;
  skeleton?: {
    bones: UUID[];                 // Bone 对象的 uuid 列表
    boneInverses?: Mat4[];         // 可选
  };
}

interface Line extends Object3DBase {
  type: "Line" | "LineSegments" | "LineLoop";
  geometry?: UUID;
  material?: UUID;
}

interface Points extends Object3DBase {
  type: "Points";
  geometry?: UUID;
  material?: UUID;
}

interface Sprite extends Object3DBase {
  type: "Sprite";
  material?: UUID;
  center?: Vec2;
}

interface Group extends Object3DBase {
  type: "Group";
}

interface Bone extends Object3DBase {
  type: "Bone";
}

type Object3D =
  | Scene
  | PerspectiveCamera
  | OrthographicCamera
  | Camera
  | AmbientLight
  | HemisphereLight
  | DirectionalLight
  | PointLight
  | SpotLight
  | RectAreaLight
  | Mesh
  | Line
  | Points
  | Sprite
  | Group
  | Bone
  | (Object3DBase & { [k: string]: unknown }); // 兜底扩展

/* ===== Fog ===== */

type Fog =
  | { type: "Fog"; color: ColorHex; near: number; far: number }
  | { type: "FogExp2"; color: ColorHex; density: number };

/* ===== Geometry（以 BufferGeometry 为主） ===== */

interface Geometry {
  uuid: UUID;
  type: string; // "BufferGeometry" | 具体几何类型（BoxGeometry/CylinderGeometry 等）视版本而定
  name?: string;
  data?: BufferGeometryData; // BufferGeometry 底层数据
  // 某些旧版本/手写导出会把参数（parameters）直接放在此处：
  parameters?: Record<string, unknown>;
  [extra: string]: unknown;
}

interface BufferGeometryData {
  attributes: Record<
    string,
    BufferAttribute | InterleavedBufferAttribute
  >;
  index?: BufferAttribute | InterleavedBufferAttribute;
  morphAttributes?: Record<string, BufferAttribute[]>;
  morphTargetsRelative?: boolean;

  groups?: { start: number; count: number; materialIndex?: number }[];

  boundingBox?: { min: Vec3; max: Vec3 };
  boundingSphere?: { center: Vec3; radius: number };

  drawRange?: { start: number; count: number };
  [extra: string]: unknown;
}

interface BufferAttribute {
  itemSize: number;
  type: string; // e.g. "Float32Array" | "Uint16Array" ...
  array: number[]; // 导出为普通 number 数组
  normalized?: boolean;
}

interface InterleavedBufferAttribute {
  itemSize: number;
  type: string;
  data: {
    buffer: number[]; // 展平数据
    stride: number;
    type: string;
  };
  offset: number;
  normalized?: boolean;
}

/* ===== Materials ===== */

interface MaterialBase {
  uuid: UUID;
  type: string; // "MeshStandardMaterial" | "MeshPhysicalMaterial" | "PointsMaterial" | "LineBasicMaterial" | ...
  name?: string;

  color?: ColorHex;
  opacity?: number;
  transparent?: boolean;
  alphaTest?: number;
  depthTest?: boolean;
  depthWrite?: boolean;
  colorWrite?: boolean;
  side?: number; // FrontSide/BackSide/DoubleSide
  blending?: number;
  blendSrc?: number;
  blendDst?: number;
  blendEquation?: number;
  blendSrcAlpha?: number;
  blendDstAlpha?: number;
  blendEquationAlpha?: number;
  polygonOffset?: boolean;
  polygonOffsetFactor?: number;
  polygonOffsetUnits?: number;
  dithering?: boolean;
  toneMapped?: boolean;
  visible?: boolean;
  vertexColors?: boolean | number; // 新旧差异

  // map/纹理引用（均为纹理 uuid）
  map?: UUID | null;
  alphaMap?: UUID | null;
  aoMap?: UUID | null;
  aoMapIntensity?: number;
  bumpMap?: UUID | null;
  bumpScale?: number;
  normalMap?: UUID | null;
  normalScale?: Vec2;
  displacementMap?: UUID | null;
  displacementScale?: number;
  displacementBias?: number;
  emissive?: ColorHex;
  emissiveIntensity?: number;
  emissiveMap?: UUID | null;
  envMap?: UUID | null;
  envMapIntensity?: number;
  lightMap?: UUID | null;
  lightMapIntensity?: number;
  metalness?: number;
  metalnessMap?: UUID | null;
  roughness?: number;
  roughnessMap?: UUID | null;

  // Physical/Transmission/Sheen/Iridescence/Anisotropy 等（按需出现）
  clearcoat?: number;
  clearcoatRoughness?: number;
  clearcoatNormalMap?: UUID | null;
  clearcoatNormalScale?: Vec2;

  sheen?: number | Vec3;
  sheenColor?: ColorHex;
  sheenRoughness?: number;
  sheenColorMap?: UUID | null;
  sheenRoughnessMap?: UUID | null;

  transmission?: number;
  transmissionMap?: UUID | null;
  thickness?: number;
  thicknessMap?: UUID | null;
  attenuationColor?: ColorHex;
  attenuationDistance?: number;
  ior?: number;

  specularIntensity?: number;
  specularIntensityMap?: UUID | null;
  specularColor?: ColorHex;
  specularColorMap?: UUID | null;

  iridescence?: number;
  iridescenceIOR?: number;
  iridescenceThicknessRange?: Vec2;
  iridescenceThicknessMap?: UUID | null;

  anisotropy?: number;
  anisotropyMap?: UUID | null;
  anisotropyRotation?: number;

  // Shader/Node/Raw/Phong/Lambert/Matcap 等材质的补充字段：
  wireframe?: boolean;
  wireframeLinewidth?: number;
  flatShading?: boolean;
  shininess?: number;
  reflectivity?: number;
  refractionRatio?: number;
  gradientMap?: UUID | null;
  matcap?: UUID | null;

  skinning?: boolean;
  morphTargets?: boolean;
  morphNormals?: boolean;

  defines?: Record<string, unknown>;
  uniforms?: Record<string, unknown>;
  extensions?: Record<string, boolean>;
  glslVersion?: number;

  userData?: Record<string, unknown>;

  [extra: string]: unknown;
}

type Material = MaterialBase;

/* ===== Textures & Images ===== */

interface Texture {
  uuid: UUID;
  name?: string;

  image?: UUID | ImageData; // 常见为 image: <image uuid>；DataTexture 会内联 data
  mapping?: number;
  channel?: number;

  wrap?: [number, number]; // [wrapS, wrapT]
  wrapS?: number;
  wrapT?: number;
  magFilter?: number;
  minFilter?: number;
  anisotropy?: number;

  format?: number;
  type?: number;      // 数据类型
  encoding?: number;

  flipY?: boolean;
  premultiplyAlpha?: boolean;

  repeat?: Vec2;
  offset?: Vec2;
  center?: Vec2;
  rotation?: number;
  matrixAutoUpdate?: boolean;

  // 立方体纹理/3D 纹理/视频纹理等会有额外键：
  isRenderTargetTexture?: boolean;
  uvTransform?: number[]; // 某些版本

  userData?: Record<string, unknown>;
  [extra: string]: unknown;
}

interface ImageFile {
  uuid: UUID;
  url: string; // 外链或相对路径
}

interface ImageData {
  uuid: UUID;
  data: number[] | string; // DataTexture 可能是 base64 / 数组
  width: number;
  height: number;
  // 可选元信息
  type?: number;
  format?: number;
}

type Image = ImageFile | ImageData;

/* ===== Animations ===== */

interface AnimationClip {
  name: string;
  duration: number; // 秒
  tracks: KeyframeTrack[];
  blendMode?: number;
  uuid?: UUID;
}

interface KeyframeTrack {
  name: string; // 目标路径：e.g. "Bone001.position" / ".quaternion" / "mesh.morphTargetInfluences[Smile]"
  type: string; // e.g. "number", "vector", "quaternion", "color"（或具体 Track 类名）
  times: number[];  // 关键帧时间（秒）
  values: number[]; // 扁平数值
  interpolation?: number; // InterpolateLinear 等
}

interface BodyOption {
  // 
  key: string;
  name: string;
  // 前缀
  prefix: string;
  // 后缀
  suffix: string;
}
interface Body {
  // 主体模型名称
  name: string;
  // 部位描述
  options: BodyOption[];
}
interface ModelDescription {
  name: string
  model: Object3DBase & { body: Body; rotate?: boolean }
  scene?: Object3DBase
  camera: ThreeJSON<Camera>
  lights: ThreeJSON<Light>[]
  orbitControls: ThreeJSON<OrbitControls>
  gridHelper?: {
    size?: number
    divisions?: number
    color1?: string | number
    color2?: string | number
  }
  debug?: boolean
  dracoPath?: string
}
/**
 * 
模型信息
 */
interface ModelInfo {
  /** 角色对象 */
  actor: THREE.Group<THREE.Object3DEventMap>;
  /** 场景对象列表 */
  scenes: THREE.Object3D[];
  /** 动画剪辑列表 */
  animations: THREE.AnimationClip[];
  /** 动画混合器 */
  mixer: THREE.AnimationMixer;
  /** 动画动作列表 */
  actions: any[];
}

/**
 * 动画播放选项
 */
interface PlayActionOptions {
  /** 循环模式 */
  loop?: THREE.AnimationActionLoopStyles;
  /** 重复次数 */
  repetitions?: number;
  /** 过渡时间（秒），默认 0.5 */
  fadeDuration?: number;
}

/**
 * 加载器响应
 */
interface LoaderResponse {
  /** 模型 ID */
  id: string;
  /** 模型名称 */
  name: string;
  /** 模型代码 */
  code: string;
  /** 模型文件路径 */
  bundle: string;
  /** 模型类型 */
  type: 'apose' | 'animation' | 'animation_system';
  /** 是否启用 */
  enabled?: boolean;
  /** 缓冲数据 */
  buffer?: any;
  /** GLTF 对象 */
  gltf?: GLTF;
}

/**
 * 加载进度
 */
interface LoaderProgress {
  /** 资源 URL */
  url: string;
  /** 进度值 (0-1) */
  progress: number;
  /** 数据总量（字节）或百分比 */
  total: number;
}

/**
 * 模型文件
 */
interface ModelFile {
  /** 文件名 */
  name: string;
  /** 文件类型 */
  type: 'zip' | 'bundle' | 'glb' | '';
  /** 解压密码（zip 类型） */
  pwd?: string;
  /** 文件路径 */
  url: string;
}

/**
 * 场景类型
 */
type SceneType = 'hdr' | 'picture' | 'glb' | 'background' | 'video';

/**
 * 场景配置
 */
interface SceneConfig {
  /** 场景 ID */
  id: string;
  /** 场景名称 */
  name: string;
  /** 场景路径 */
  path: string;
  /** 场景类型 */
  type: SceneType;
  /** 图片列表 */
  pictures?: string[];
  /** 背景 */
  background?: string;
}

/**
 * 配置相关类型定义
 * @module types/config
 */



/**
 * 数字人角色类型
 */
type Character = 'xiaomeng' | 'custom' | 'quan' | 'doctor' | 'boy' | 'girl' | '';

/**
 * 运行模式
 * - `normal`: 普通模式，支持所有功能
 * - `voice`: 语音交互模式（已废弃）
 * - `render-only`: 仅渲染模式，不加载交互功能
 */
type Mode = 'normal' | 'voice' | 'render-only';

/**
 * 服务器配置
 * 用于配置 API 服务和 WebSocket 服务的地址
 */
interface ServerConfig {
  /** 
   * API 服务地址
   * @default process.env.ROLLUP_BASE_API
   * @example 'https://console-api.qtworld.top'
   */
  api?: string;
  
  /** 
   * Gateway WebSocket 服务地址（推荐使用）
   * 统一的 WebSocket 网关，用于 LLM、TTS、ASR 功能
   * @default 'wss://qt-gateway.quantekeji.com/api/ws'
   * @example 'wss://qt-gateway.quantekeji.com/api/ws'
   */
  gateway?: string;
  
  /** 
   * 旧版 WebSocket 服务地址（将被废弃）
   * @deprecated 请使用 gateway 配置
   */
  wss?: string;
}

/**
 * 音频配置
 * 用于控制音频播放的音量和静音状态
 */
interface AudioConfig {
  /** 
   * 音量大小，范围 0-1
   * @default 1.0
   * @example 0.8
   */
  volume?: number;
  
  /** 
   * 是否静音
   * @default false
   */
  muted?: boolean;
}

/**
 * 渲染配置
 * 用于控制 3D 渲染的性能和质量
 */
interface RenderConfig {
  /** 
   * 渲染帧率
   * @default 30
   * @example 60
   */
  fps?: number;
  
  /** 
   * 渲染质量
   * - `low`: 低质量，性能优先
   * - `medium`: 中等质量，平衡性能和质量
   * - `high`: 高质量，质量优先
   * @default 'medium'
   */
  quality?: 'low' | 'medium' | 'high';
}

/**
 * 语音模式配置
 * @deprecated 语音交互模式已废弃
 */
interface VoiceModeConfig {
  /** 
   * 为 true 时不会受到唤醒词、退出词和打断词的影响，程序会一直收音并且会随时打断
   * @default false
   * @deprecated
   */
  keepActive?: boolean;
}

/**
 * LLM 请求参数配置
 * 用于控制 LLM 对话生成的行为
 */
interface QuestionApiParams {
  /**
   * LLM 模型名称
   * @default 'quan'
   */
  model?: string;
  /**
   * 最大生成 token 数
   * @default 256
   */
  max_tokens?: number;
  /**
   * 生成温度，越高越随机
   * @default 0.95
   */
  temperature?: number;
  /**
   * 是否使用流式传输
   * @default false
   */
  stream?: boolean;
  /**
   * 是否启用句级分割
   * @default true
   */
  sentence?: boolean;
  /**
   * 是否使用 SSE 推送
   * @default true
   */
  sse?: boolean;
}

/**
 * TTS 请求参数配置
 * 用于控制语音合成的行为
 */
interface TTSApiParams {
  /**
   * 语音角色
   * @default 'xiaoxiao'
   */
  role?: string;
  /**
   * 语速倍率
   * @default 1
   */
  speed?: number;
  /**
   * TTS 序列号
   * @default 10
   */
  sn?: number;
  /**
   * TTS 模型
   * @default 'paddle2'
   */
  model?: string;
  /**
   * 口型格式
   * @default 'a2f'
   */
  viseme?: string;
  /**
   * 平滑算法
   * @default 1
   */
  smooth_method?: number;
  /**
   * 平滑迭代次数
   * 注意：字段名 interations 为后端 API 历史拼写，保持一致不做修正
   * @default 5
   */
  smooth_interations?: number;
}

/**
 * 3D 模型渲染配置
 */
interface ModelRenderConfig {
  /**
   * 模型名称
   * @default 'quante'
   */
  name?: string;
  /** 相机配置 */
  camera?: {
    /**
     * 视场角
     * @default 50
     */
    fov?: number;
  };
  /** 轨道控制器限制 */
  orbitControls?: {
    /**
     * 最小极角（弧度）
     * @default 0
     */
    minPolarAngle?: number;
    /**
     * 最大极角（弧度）
     * @default Math.PI
     */
    maxPolarAngle?: number;
  };
}

/**
 * 加密配置
 * 用于模型加载时的 AES 解密
 */
interface CryptoConfig {
  /** AES 加密盐值 */
  salt?: string;
  /** AES 初始化向量 */
  iv?: string;
}

/**
 * 语音交互配置
 * 用于配置 WebRTC 语音交互模式
 */
interface VoiceConfig {
  /**
   * 唤醒词列表
   * 当识别到这些词时，进入激活状态开始对话
   * @example ['你好', '你好小全']
   */
  wakeWords?: string[];

  /**
   * 退出词列表（休眠）
   * 当识别到这些词时，退出激活状态进入休眠
   * @example ['关闭', '退出']
   */
  exitWords?: string[];

  /**
   * 打断词列表
   * 当识别到这些词时，打断当前播放
   * @example ['停止', 'stop', '返回']
   */
  interruptWords?: string[];

  /**
   * 音频采样率
   * @default 16000
   */
  sampleRate?: number;

  /**
   * 无操作时退出时间（毫秒）
   * 激活状态下无操作超过此时间后自动进入休眠
   * @default 30000
   */
  exitTime?: number;

  /**
   * 是否保持常开模式
   * 为 true 时不受唤醒词、退出词影响，始终处于激活状态
   * @default false
   */
  keepActive?: boolean;

  /**
   * 是否自动开始对话
   * 为 true 时识别到语音后自动发送给 LLM
   * @default true
   */
  autoAsk?: boolean;

  /**
   * 静音检测时间（毫秒）
   * 用户停止说话后等待此时间确认语音结束
   * @default 1500
   */
  silenceTimeout?: number;

  /**
   * 是否启用 A2F 口型
   * @default true
   */
  a2fEnabled?: boolean;

  /** 是否要求唤醒词说两遍（如"小德小德"），默认 false（向后兼容） */
  doubleWakeWord?: boolean

  /** 唤醒确认语，如"在呢"。唤醒后通过直接 TTS 播报（不走 LLM，不入历史） */
  wakeConfirmText?: string

  /** 额外 synthetic 白名单文本（如工具确认语），通过 CMD 1031 下发给 Gateway 做会话级校验 */
  syntheticTexts?: string[]

  /** 连续对话窗口时长（ms），TTS 结束后保持监听，默认使用 exitTime */
  continuousWindowMs?: number

  /** 优雅退出提示语，如"还有什么要问的吗？"。通过直接 TTS 播报 */
  gracefulExitPrompt?: string

  /** 是否启用优雅退出（先提示再休眠），默认 false */
  gracefulExitEnabled?: boolean

  /** 严格打断模式：TTS 播放中仅角色名可打断（排除 interruptWords），默认 false */
  bargeInStrictMode?: boolean

  // ─── 高级调优参数 ───

  /**
   * 打断冷却时间（毫秒）
   * @default 500
   */
  bargeInCooldownMs?: number;

  /**
   * LLM 请求超时（毫秒）
   * @default 30000
   */
  llmTimeoutMs?: number;

  /**
   * LLM 最大重试次数
   * @default 2
   */
  llmMaxRetry?: number;

  /**
   * WebRTC 重连间隔（毫秒）
   * @default 3000
   */
  webrtcReconnectInterval?: number;

  /**
   * WebRTC 最大重连次数
   * @default 3
   */
  webrtcMaxReconnectAttempts?: number;

  /**
   * VAD 触发窗口（毫秒），唤醒后在此窗口内 VAD 处于门控状态
   * @default 2500
   */
  vadGateWindowMs?: number;

  /**
   * VAD 宽限期（毫秒），TTS 播放结束后的 VAD 静默宽限
   * @default 4000
   */
  vadGraceMs?: number;

  /**
   * 打断后跟进窗口（毫秒），打断后保持监听的时间
   * @default 6000
   */
  interruptFollowUpWindowMs?: number;

  /**
   * 优雅退出 Phase2 提示语
   * @default '如果没有其他问题，我先休息了哦'
   */
  gracefulExitPhase2Prompt?: string;

  /**
   * 优雅退出 Phase2 静默时间（毫秒）
   * @default 60000
   */
  gracefulExitPhase2Silence?: number;

  /**
   * 优雅退出 Phase3 静默时间（毫秒）
   * @default 30000
   */
  gracefulExitPhase3Silence?: number;

  /**
   * 打断词过滤窗口（毫秒），唤醒后在此窗口内过滤打断词
   * @default 3000
   */
  interruptWordFilterMs?: number;

  /**
   * 欢迎语后 ASR 恢复延迟（毫秒）
   * @default 1200
   */
  welcomeAsrResumeDelayMs?: number;

  /**
   * 语音提问超时（毫秒），由 Human 编排层消费（非 VoiceConversation）
   * 仅在使用 Human.openVoiceInteraction() 旧版语音模式时生效
   * @default 120000
   */
  voiceAskTimeout?: number;

  /**
   * TTS 播放安全超时（毫秒），由 Human 编排层消费（非 VoiceConversation）
   * 超时后强制结束播放，防止 isTTSPlaying 状态卡住
   * @default 30000
   */
  ttsSafetyTimeoutMs?: number;
}

/**
 * Human 初始化配置
 * 用于创建数字人实例时的配置选项
 * 
 * @example
 * ```typescript
 * const config: HumanConfig = {
 *   token: 'your-auth-token',
 *   container: 'human-container',
 *   characterId: 'your-character-id',
 *   audio: {
 *     volume: 0.8,
 *     muted: false
 *   },
 *   render: {
 *     fps: 60,
 *     quality: 'high'
 *   }
 * }
 * 
 * const human = new Human(config)
 * ```
 */
interface HumanConfig {
  /** 
   * 授权 Token（必填）
   * 从 qtworld 平台获取的授权令牌
   * @see https://console.quantekeji.com/login
   */
  token: string;
  
  /** 
   * 渲染容器
   * 可以是 DOM 元素的 ID 字符串或 HTMLElement 对象
   * 如果不提供，则只加载模型不渲染
   * @example 'human-container'
   * @example document.getElementById('container')
   */
  container?: string | HTMLElement;
  
  /** 
   * 数字人 ID
   * 从 qtworld 平台获取的数字人标识
   * @example 'character-123456'
   */
  characterId?: string;
  
  /**
   * 服务配置
   * 配置 API 服务和 WebSocket 服务的地址
   */
  server?: ServerConfig;

  /**
   * iOS 音频实验模式
   * - `baseline`: 保持当前线上行为（禁用浏览器 AEC）
   * - `aec`: 启用 echoCancellation/noiseSuppression，AGC 关闭
   * - `aec_full`: 启用 echoCancellation/noiseSuppression/AGC
   * @default 'baseline'
   */
  iosAudioMode?: 'baseline' | 'aec' | 'aec_full';
  
  /** 
   * 音频配置
   * 控制音频播放的音量和静音状态
   */
  audio?: AudioConfig;
  
  /** 
   * 渲染配置
   * 控制 3D 渲染的性能和质量
   */
  render?: RenderConfig;
  
  /** 
   * 运行模式
   * - `normal`: 普通模式（默认）
   * - `voice`: 语音交互模式（已废弃）
   * - `render-only`: 仅渲染模式
   * @default 'normal'
   */
  mode?: Mode;
  
  /** 
   * 语音模式配置
   * @deprecated 语音交互模式已废弃
   */
  voiceModeConfig?: VoiceModeConfig;
  
  /** 
   * 加载动画元素
   * 可以是 DOM 元素的 ID 字符串或 HTMLElement 对象
   * 用于显示加载进度
   * @example 'loading-container'
   */
  loading?: string | HTMLElement;
  
  /** 
   * 加载完成后是否销毁加载动画
   * @default true
   */
  loadingDestroy?: boolean;
  
  /** 
   * 是否立即渲染
   * 为 true 时不会自动开始渲染，需要手动调用 startRender()
   * @default false
   */
  isNotRender?: boolean;
  
  /** 
   * 调试模式
   * 开启后会输出更多日志信息
   * @default false
   */
  debug?: boolean;
  
  /**
   * 3D 模型渲染配置
   * 控制相机视角和轨道控制器行为
   */
  modelConfig?: ModelRenderConfig;

  /**
   * LLM 请求参数
   * 控制对话生成的模型、温度、token 限制等
   */
  questionApiParams?: QuestionApiParams;

  /**
   * TTS 语音合成参数
   * 控制语音角色、语速、口型格式等
   */
  text2SpeachApiParams?: TTSApiParams;

  /**
   * 加密配置
   * 用于模型加载时的 AES 解密，不传则使用内置默认值
   */
  crypto?: CryptoConfig;
  
  /** 
   * 其他配置选项
   */
  options?: {
    /** 
     * BlendShapes 每秒执行的帧数
     * 控制面部表情和口型动画的流畅度
     * @default 30
     * @example 60
     */
    fps?: number;
  };
}

/**
 * 相机视角配置
 * 用于控制 3D 场景的相机位置和角度
 * 
 * @example
 * ```typescript
 * // 切换到正面视角
 * human.setAngleView({
 *   camera: {
 *     position: [0, 1.6, 2],
 *     fov: 50,
 *     duration: 1000  // 1秒过渡动画
 *   }
 * })
 * ```
 */
interface AngleViewConfig {
  /** 
   * 相机配置
   */
  camera?: {
    /** 
     * 相机位置 [x, y, z]
     * @example [0, 1.6, 2]
     */
    position?: [number, number, number];
    
    /** 
     * 相机旋转角度 [x, y, z]（弧度）
     * @example [0, 0, 0]
     */
    rotation?: [number, number, number];
    
    /** 
     * 视场角（Field of View）
     * @default 50
     * @example 60
     */
    fov?: number;
    
    /** 
     * 动画持续时间（毫秒）
     * 设置相机移动的过渡动画时长
     * @default 0
     * @example 1000
     */
    duration?: number;
  };
  
  /** 
   * 轨道控制器配置
   */
  controls?: {
    /** 
     * 控制器目标点 [x, y, z]
     * 相机围绕此点旋转
     * @example [0, 1, 0]
     */
    target?: [number, number, number];
    
    /** 
     * 是否启用轨道控制器
     * @default true
     */
    enabled?: boolean;
    
    /** 
     * 动画持续时间（毫秒）
     * @default 0
     * @example 1000
     */
    duration?: number;
  };
}

/**
 * 运行时内部使用的渲染配置。
 * 该结构保持后台协议的输入边界稳定，同时为后续 runtime 拆分提供明确的中间层。
 */
interface ResolvedRenderConfig {
  name?: string;
  scene?: Object3DBase;
  camera?: ThreeJSON<Camera>;
  orbitControls?: ThreeJSON<OrbitControls>;
  lights: ThreeJSON<Light>[];
  model?: Object3DBase & { body: Body; rotate?: boolean };
  gridHelper?: {
    size?: number;
    divisions?: number;
    color1?: string | number;
    color2?: string | number;
  };
  dracoPath?: string;
}

/**
 * 角色资源侧配置。
 * 保留后台当前真实下发的 scene 结构，避免阶段 0 就丢失 glb/video/picture/background 分支信息。
 */
interface ResolvedAssetSceneConfig extends Partial<NonNullable<CharacterInfo['scene']>> {
  id?: string;
  name?: string;
  type?: string;
  path?: string;
  pictures?: string[];
  background?: unknown;
}

interface ResolvedAssetConfig {
  aposes: CharacterModel[];
  animations: CharacterModel[];
  scene: ResolvedAssetSceneConfig | null;
}

interface ResolvedBehaviorConfig {
  animationEnabled: boolean;
  debug: boolean;
  isNotRender: boolean;
}

interface ResolvedCharacterConfig {
  render: ResolvedRenderConfig;
  assets: ResolvedAssetConfig;
  behavior: ResolvedBehaviorConfig;
}

/**
 * 事件相关类型定义
 * @module types/events
 */



/**
 * 加载进度事件数据
 */
interface LoadProgressEvent {
  code: 'download' | 'loaded' | 'loading';
  progress: number;
  total: number;
  url?: string;
}

/**
 * 错误事件数据
 */
interface ErrorEvent {
  code: string | number;
  message: string;
  details?: any;
}

/**
 * 音频播放事件数据
 */
interface AudioPlayEvent {
  playing: boolean;
  duration?: number;
  currentTime?: number;
}

/**
 * 语音识别事件数据
 */
interface Voice2TextEvent {
  isFinal: boolean;
  text: string;
  confidence?: number;
  /** 是否是打断触发的识别结果（用户打断 TTS 播放时为 true） */
  isBargeIn?: boolean;
}

/**
 * 人脸识别结果
 */
interface FaceRecognitionResult {
  count: number;
  faces: Array<{
    confidence: number;
    box: {
      x: number;
      y: number;
      width: number;
      height: number;
    };
    landmarks?: any[];
  }>;
}

/**
 * 人体检测结果
 */
interface PersonDetectionResult {
  count: number;
  detected: boolean;
}

/**
 * Gateway 消息事件数据
 */
interface GatewayMessageEvent {
  type: 'chat' | 'tts' | 'asr' | 'error';
  event: string;
  data: any;
  requestId?: string;
}

/**
 * 事件监听器类型
 */
type EventListener<T = any> = (data: T) => void;

/**
 * 动画播放事件数据
 */
interface AnimationEvent {
  code: string;
  name?: string;
  duration?: number;
}

/**
 * 模型加载事件数据
 */
interface ModelLoadEvent {
  code: string;
  name: string;
  type: 'apose' | 'animation' | 'animation_system';
  progress?: number;
}

/**
 * 角色动作事件数据
 * 对应 Gateway CMD: 1020
 */
interface CharacterActionEvent {
  /** 动作名称列表（兼容旧格式） */
  actions: string[];
  /** 动作名称 */
  name: string;
  /** 动作额外参数 */
  inputs: Record<string, any>;
}

/**
 * 事件映射类型
 */
interface EventMap {
  [key: string]: any;
}

type FacingMode = "user" | "environment";

interface CameraConfig {
  el: string | HTMLDivElement;
  facingMode?: FacingMode;       // 前/后摄像头
  features?: string[];           // 功能列表 ["photo", "detection"]
  overlayImage?: HTMLImageElement | null; // 合影 PNG
}

interface CameraFeature {
  name: string;
  init?(camera: CameraCore): Promise<void> | void;
  destroy?(): Promise<void> | void;
}

interface CameraCore {
  getVideoEl(): HTMLVideoElement;
  getStream(): MediaStream | null;
}

interface FaceRecognitionConfig {
  // 多长时间识别一次 单位 ms, 默认 3000ms
  duration?: number;
  // 识别人数 默认 不限
  maxResults?: number;
  // 是否在视频上绘制人脸检测框，默认 false
  drawDetections?: boolean;
  // 是否在视频上绘制人脸特征点，默认 false
  drawFaceLandmarks?: boolean;
  // 最小置信度，默认 0.6
  minConfidence?: number;
}

interface SmileDetectionConfig {
  /** happy 概率阈值，默认 0.7 */
  smileThreshold?: number
  /** 触发冷却时间（ms），默认 30000，仅控制 DETECTED 边沿事件 */
  cooldownMs?: number
  /** face-api 模型文件目录 URI，默认使用 ROLLUP_BASE_STATIC/models */
  modelUri?: string
  /** 最大检测人脸数，默认 10 */
  maxFaces?: number
}

/** 微笑状态事件 payload */
interface SmileStateData {
  /** 当前画面中"微笑"判定（happy >= smileThreshold）的人脸数 */
  smileCount: number
  /** 当前画面中检测到的总人脸数 */
  totalFaces: number
  /** 当前画面中所有人脸的最大"开心"置信度（0-1）；totalFaces 为 0 时为 0 */
  maxHappiness: number
  /** 时间戳 */
  timestamp: number
}

/**
 * Human 类相关类型定义
 */



/**
 * Human 类接口
 * 数字人核心 API
 */
interface IHuman extends Emittery {
  /** 数字人名称 */
  name: string;

  /**
   * Gateway session id (populated after CmdLoginSuccess / 1007).
   * Empty string before WS login completes. Read-only.
   */
  readonly sessionId: string;

  /**
   * Phase 1B-β.7: enable / disable server-push proactive TTS playback.
   *
   * When enabled, raw TTS audio frames pushed by gateway (without a client request,
   * e.g. proactive "hi 张老师" when camera spots a known user) are routed to the
   * internal FramePlayer for playback. Default OFF for back-compat.
   *
   * Safe to call after `init()`. Does not interfere with voiceConversation / sendTTS.
   */
  enableProactiveTTSPlayback(enable?: boolean): void;

  // ========== 模型管理 ==========

  /**
   * 设置数字人模型
   * @param characterId 数字人 ID
   * @param config 可选的配置参数
   * @returns Promise<boolean> 是否成功
   */
  setCharacter(characterId: string, config?: Partial<HumanConfig>): Promise<boolean>;

  /**
   * 设置数字人模型数据
   * @param characterId 数字人 ID
   * @returns Promise<boolean> 是否成功
   */
  setCharacterData(characterId: string): Promise<boolean>;

  /**
   * 获取模型信息
   * @returns ModelInfo | null 模型信息对象
   */
  getModelInfo(): ModelInfo | null;

  /**
   * 离线渲染模型（不可使用 ASR、TTS、咨询大模型等功能）
   * @param files 模型文件列表
   * @returns Promise<boolean> 是否成功
   */
  offlineRender(files: CharacterModel[]): Promise<boolean>;

  // ========== 对话功能 ==========

  /**
   * AI 流式问答
   * @param params 问答参数
   * @param callback 回调函数
   * @returns Promise<Result<AskStreamResponse>> 问答响应
   */
  askStream(params: AskParams, callback: (msgs: Result$1<ChatMessage[]>) => void): Promise<Result$1<AskStreamResponse>>;

  /**
   * AI 问答（非流式）
   * @param params 问答参数
   * @param callback 回调函数
   * @returns Promise<Result<AskResponse>> 问答响应
   */
  ask(params: AskParams, callback: AskCallback): Promise<Result$1<AskResponse>>;

  /**
   * 文本播报
   * @param text 播报文本
   * @param callback 可选的回调函数
   * @returns Promise<StreamAudioPlayInfo> 播放信息
   */
  speak(text: string, callback?: SpeakCallback): Promise<StreamAudioPlayInfo>;

  /**
   * 停止当前播报和动作
   * @returns Promise<boolean> 是否成功
   */
  stop(): Promise<boolean>;

  /**
   * 使用音频和 BlendShapes 播报
   * @param uris 音频 URL 列表
   * @param shapes BlendShapes 数据列表
   * @returns Promise<boolean> 是否成功
   */
  speakByAudioShapes(uris: string[], shapes: Array<number[][]>): Promise<boolean>;

  // ========== 音频控制 ==========

  /**
   * 音频静音控制
   * @param isMute true: 静音，false: 取消静音
   */
  muteAudio(isMute: boolean): void;

  /**
   * 动作禁用控制
   * @param isMute true: 禁用，false: 取消禁用
   */
  muteAction(isMute: boolean): void;

  // ========== 语音交互 ==========

  /**
   * 开始语音转文本
   * @param callback 可选的回调函数
   * @returns Promise<Result<RecorderPermission>> 录音权限结果
   */
  startVoice2Text(callback?: Voice2TextCallback): Promise<Result$1<RecorderPermission>>;

  /**
   * 停止语音转文本
   * @param callback 可选的回调函数
   * @returns Promise<Result<null>> 结果
   */
  stopVoice2Text(callback?: Voice2TextCallback): Promise<Result$1<null>>;

  /**
   * 打开语音交互模式
   * @param config 语音配置
   * @returns Promise<boolean> 是否成功
   */
  openVoiceInteraction(config: VoiceConfig): Promise<boolean>;

  /**
   * 关闭录音器
   * @returns Promise<boolean> 是否成功
   */
  closeRecorder(): Promise<boolean>;

  /**
   * 打开录音器
   * @returns Promise<Result<RecorderPermission>> 录音权限结果
   */
  openRecorder(): Promise<Result$1<RecorderPermission>>;

  // ========== 渲染控制 ==========

  /**
   * 开始渲染
   * @returns Promise<boolean> 是否成功
   */
  startRender(): Promise<boolean>;

  /**
   * 停止渲染
   * @returns Promise<boolean> 是否成功
   */
  stopRender(): Promise<boolean>;

  /**
   * 切换视角
   * @param config 视角配置
   */
  setAngleView(config: AngleViewConfig): void;

  /**
   * 执行动画
   * @param code 动画代码
   * @param opts 播放选项
   * @returns Promise<void>
   */
  playAction(code: string, opts?: PlayActionOptions): Promise<void>;

  // ========== 摄像头功能 ==========

  /**
   * 打开摄像头
   * @param config 摄像头配置
   * @returns Promise<boolean> 是否成功
   */
  openCamera(config: CameraConfig): Promise<boolean>;

  /**
   * 开始人脸识别
   * @param config 人脸识别配置
   * @returns Promise<boolean> 是否成功
   */
  startFaceRecognition(config: FaceRecognitionConfig): Promise<boolean>;

  /**
   * 停止人脸识别
   * @returns Promise<boolean> 是否成功
   */
  stopFaceRecognition(): Promise<boolean>;

  /**
   * 开始人体检测
   * @returns Promise<boolean> 是否成功
   */
  startBodyDetect(): Promise<boolean>;

  /**
   * 停止人体检测
   * @returns Promise<boolean> 是否成功
   */
  stopBodyDetect(): Promise<boolean>;

  /**
   * 开始微笑检测
   * @param config 微笑检测配置
   * @returns Promise<boolean> 是否成功
   */
  startSmileDetection(config?: SmileDetectionConfig): Promise<boolean>;

  /**
   * 停止微笑检测
   * @returns boolean 是否成功
   */
  stopSmileDetection(): boolean;

  /**
   * 关闭摄像头并清理资源（含 DOM）
   */
  closeCamera(): void;

  // ========== 资源管理 ==========

  /**
   * 更新授权 Token
   * @param token 新的 Token
   */
  updateToken(token: string): void;

  /**
   * 销毁实例，释放所有资源
   */
  destroy(): void;
}

/**
 * Human 类构造函数参数
 */
type HumanConstructorParams = HumanConfig;

/**
 * Human 类
 */
interface HumanConstructor {
  new (config: HumanConfig): IHuman;
}

declare class ThreeJSApp extends Emittery {
    private animationFrameId;
    private container;
    private scene;
    private camera;
    private renderer;
    private controls;
    private width;
    private height;
    private readonly depth;
    private config;
    private isNotRender;
    private clock;
    private body;
    private characterGroup;
    private lightGroup;
    private state;
    private onWindowResizeBound;
    private rotationCenter;
    private _container;
    private gui;
    private humanObj;
    private sceneManager;
    private interactionManager;
    private backgroundManager;
    private animationManager;
    private blendShapeManager;
    private modelRuntime;
    private resourceCleaner;
    constructor(container: (string | HTMLElement) | undefined, config: ModelDescription, humanObj: Human);
    private syncSceneRuntime;
    init(): void;
    private createDefaultCamera;
    private createRenderer;
    setContainer(): void;
    updateLight(): void;
    initLights(lights?: Light[] | ThreeJSON<Light>[]): void;
    loadCamera(json?: any): THREE.PerspectiveCamera | undefined;
    loadScene(json: Object3DBase | THREE.Object3D | undefined): {
        scene?: THREE.Scene;
        camera?: THREE.PerspectiveCamera;
    };
    degree2Euler(xyz: XYZ): XYZ;
    private dataToMatrix4;
    setLight(light: Light): void;
    setAngleView({ camera }: {
        camera: TCamera & {
            duration?: number;
        };
    }): void;
    gsapContainer(opts: {
        attr?: {
            [key: string]: any;
        };
    }): Promise<unknown>;
    initOrbitControls(): void;
    setBackground(bg?: string): void;
    loadGLBModel(glbURL: string): void;
    loadLowResTexture(url: string): Promise<unknown>;
    changeBundle(record: LoaderResponse): void;
    loadBundles(list: LoaderResponse[], onProgress: (progress: number) => void): Promise<boolean>;
    onWindowResize: lodash.DebouncedFuncLeading<() => void>;
    setCamera(camera: THREE.PerspectiveCamera, options: TCamera): void;
    animate(): void;
    startRender(): void;
    stopRender(): void;
    gsapMorph(target: number[], source: number[], t2: any): void;
    playAction: (code: string | string[], opts?: PlayActionOptions) => void;
    stopAllActionExcludeIdle(): void;
    stopAllAction(): void;
    cleanMaterial(material: THREE.Material | THREE.Material[]): void;
    destroy(): void;
    private clearReferences;
    playByShapes(shapes?: number[], idx?: number): Promise<void>;
    stopServerShapes(): void;
    addModel(code: string, modelUrl: string): void;
    destoryModel(code: string): void;
    muteAction(isMute?: boolean): void;
    getModelInfo(): ModelInfo;
    loadGlb(url: string, onProgress?: (event: ProgressEvent) => void): Promise<GLTF>;
    addGlb(url: string, onProgress?: (event: ProgressEvent) => void): Promise<GLTF>;
    setCharacterCenter(): void;
    setVideoBackground(videoURL: string): void;
    loadCubeBackground(imageURLs: string[]): void;
    updateBackgroundSize(bgTexture: THREE.Texture, bgMesh: THREE.Mesh): void;
    setBackgroundColorOrGradient(colorOrGradient: string): void;
}
//# sourceMappingURL=render.d.ts.map

declare class Loading {
    hm: Human;
    animationFrameId: number;
    container: HTMLElement;
    scene: THREE.Scene;
    width: number;
    height: number;
    depth: number;
    zAxisNumber: number;
    camera: THREE.PerspectiveCamera;
    renderer: THREE.WebGLRenderer;
    sphere: any;
    parameters: any[];
    materials: any[];
    particles_init_postion: number;
    zprogress: number;
    zprogress_second: number;
    particles_first: any[];
    particles_second: any[];
    constructor(container: string | HTMLElement, hm: Human);
    initProgressBar(): void;
    initScene(): void;
    initCamera(): void;
    initRenderer(): void;
    initOrbitControls(): void;
    animate(): void;
    initLight(): void;
    renderSphereRotate(): void;
    initSceneStar(initZpostion: number): THREE.Points<THREE.BufferGeometry<THREE.NormalBufferAttributes>, any, THREE.Object3DEventMap>[];
    renderStarMove(): void;
    onProgress({ progress, total }: LoaderProgress): void;
    destroy(): void;
}
//# sourceMappingURL=loading.d.ts.map

interface IResult {
    code: number;
    msg: string;
}
interface IResultData<T = any> extends IResult {
    data: T;
}

type FramePlayerConfig = {
    fps?: number;
};
declare class FramePlayer extends Emittery {
    private blendShapes;
    private audioBuffer;
    private audioBufferReadIndex;
    private static readonly AUDIO_BUFFER_CLEANUP_THRESHOLD;
    private get unreadAudioCount();
    private playInfo;
    private fps;
    isPlaying: boolean;
    private isInited;
    private isIntervalStarted;
    private time;
    private idx;
    private playShapeFn;
    private lastBlendShapeLength;
    private lastBlendShape;
    private lastTimedFrameAt;
    private lastShapeReceivedAt;
    private isTransitioningToIdle;
    private transitionProgress;
    private static readonly TRANSITION_DURATION_MS;
    private static readonly TRANSITION_FRAMES;
    private static readonly MAX_SYNC_DRIFT_MS;
    private static readonly END_GRACE_MS;
    private static readonly REBASE_COOLDOWN_MS;
    private lastRebaseAt;
    private audioManager;
    private timerId;
    private callbackMap;
    private isAudioEnded;
    private audioStreamEndedTime;
    private static readonly DELAYED_PACKET_THRESHOLD_MS;
    private waitingForAudio;
    private isAudioMuted;
    private isAppendingAudio;
    private isDestroyed;
    private totalAudioBytesReceived;
    private totalBlendShapesReceived;
    private actualFps;
    private playbackStartTime;
    private framesPlayedSinceStart;
    private useAudioOffsetSync;
    private timedBlendShapes;
    private firstAudioOffset;
    private lastPlayedOffset;
    private totalWaitTime;
    private waitStartTime;
    private audioPlaybackStartTime;
    private isAudioPlaybackStarted;
    private firstAudioDataTime;
    private isFirstAudioDataReceived;
    private externalAudioTimeProvider;
    private playAudioThroughAudioManager;
    private hasReceivedRealShape;
    private usingDefaultShape;
    private defaultShapeFrameCount;
    private planBDelayTimer;
    private static readonly PLAN_B_DELAY_MS;
    private quickStartMode;
    constructor(config: FramePlayerConfig | undefined, playShapeFn: (bs: number[], idx: number) => void);
    private checkStartPlay;
    startIntervalFPS(onFrame: (time: number) => void): void;
    addShapes(blendShapes: number[][], audioOffset?: number): void;
    addBinaryAudio(buffer: ArrayBuffer): void;
    private startPlaybackPlanA;
    private startPlaybackPlanB;
    markAudioStreamEnded(): void;
    private resetSyncState;
    clear(): Promise<void>;
    private appendAudio;
    play(): Promise<void>;
    startMouthCloseTransition(): number;
    private findAndPlayFrame;
    private playTimedBlendShape;
    private playTransitionFrame;
    private finishPlayback;
    getPlayInfo(): StreamAudioPlayInfo;
    setAudioRate(rate: number): Promise<void>;
    setExternalAudioTimeProvider(provider: (() => number) | null): void;
    setPlayAudioThroughAudioManager(enable: boolean): void;
    setAudioMuted(muted: boolean): Promise<void>;
    duckAudio(tempGain: number, durationMs: number): void;
    enableAudio(): Promise<void>;
    private autoResetForNewTTS;
    prepareForNewTTS(quickStart?: boolean): void;
    getPlayingStatus(): boolean;
    getBlendShapes(): number[][];
    registerCallback(key: any, fn: (...args: any[]) => void): void;
    invokeCallback(key: string, ...args: any[]): void;
    destroy(): Promise<void>;
}

type ProximityState = 'near' | 'far' | 'stable';
declare class CameraSDK {
    private manager;
    private features;
    private container;
    private video;
    constructor(config: CameraConfig);
    open(): Promise<boolean>;
    isOpen(): boolean;
    close(): void;
    takePhoto(): Promise<string>;
    switchCamera(facingMode: "user" | "environment"): Promise<void>;
    startFaceRecognition(config: FaceRecognitionConfig, callback: Function): Promise<boolean>;
    stopFaceRecognition(): Promise<boolean>;
    startBodyDetect(callback: (stable: ProximityState) => void): Promise<boolean>;
    stopBodyDetect(): Promise<boolean>;
    startSmileDetection(config: SmileDetectionConfig, onDetected: () => void, onStateChanged: (data: SmileStateData) => void): Promise<boolean>;
    stopSmileDetection(): boolean;
    destroy(): void;
}

declare class Human extends Emittery implements IHuman {
    name: string;
    core: ThreeJSApp | null;
    private config;
    loading?: Loading;
    private audio;
    private container;
    recorder: any | null;
    private recorderMessageHandler;
    private voiceToTextManager;
    private status;
    private chatOrchestrator;
    private onAnyEvent;
    private characterData;
    private isNotRender;
    private mode;
    private gatewayService;
    framePlayer: FramePlayer | null;
    camera: CameraSDK | null;
    get sessionId(): string;
    enableProactiveTTSPlayback(enable?: boolean): void;
    private _proactiveAudioCtx;
    private voiceInteractionConfig;
    private voiceInteractionState;
    private voiceInteractionExitTimer;
    private exitPromptFired;
    private secondExitTimer;
    private exitTimerTurnId;
    private voiceInteractionConversationId;
    private voiceInteractionProcessing;
    private voiceInteractionLastText;
    private voiceInteractionLastTextTime;
    private voiceInteractionTTSMode;
    private voiceInteractionWebRTCDisabled;
    private ttsState;
    private eventBusHandlers;
    private eventBusModule;
    private _destroyed;
    private updateTokenWarnedOnce;
    private static readonly IDLE_LOOP_MODE;
    private static readonly BARGE_IN_MIN_TEXT_LENGTH;
    private static readonly BARGE_IN_COOLDOWN_MS;
    private static readonly INTERRUPT_INTENT_WORDS;
    private static readonly GREETING_ONLY_WORDS;
    private static readonly CHAR_HOMOPHONES;
    private static generateNameVariants;
    private static normalizeASRText;
    private isDoubleWakeWord;
    private speakDirect;
    private lastBargeInTime;
    private bargeInInProgress;
    private voiceInteractionAskId;
    private isAudioDataDiscarding;
    private audioDiscardingTimer;
    private static readonly AUDIO_DISCARDING_TIMEOUT_MS;
    private isFirstUserInput;
    private static readonly CONTINUATION_WINDOW_MS;
    private static readonly MIN_VALID_TEXT_LENGTH;
    private static readonly NOISE_WORDS;
    private asrTextBuffer;
    private asrSilenceTimer;
    private pendingASRFinal;
    private static readonly ASR_SILENCE_TIMEOUT_MS;
    private static readonly DUPLICATE_TEXT_WINDOW_MS;
    private pendingMergeText;
    private textMergeTimer;
    private textMergeStartTime;
    private static readonly TEXT_MERGE_DELAY_MS;
    private static readonly TEXT_MERGE_MAX_DELAY_MS;
    private ttsPlaySafetyTimer;
    private static readonly DEFAULT_TTS_PLAY_SAFETY_TIMEOUT_MS;
    private framePlayerPlayEndHandler;
    private audioDebugger;
    private webrtcLipSync;
    constructor(config: HumanConfig);
    private mergeConfig;
    private setupContainer;
    private initFramePlayer;
    private clearTTSPlaySafetyTimer;
    private replaceFramePlayerPlayEndHandler;
    private initGatewayService;
    private setupGatewayEventForwarding;
    private refreshGatewayToken;
    setCharacterData(characterId: string): Promise<boolean>;
    setCharacter(characterId: string, configuration?: Partial<HumanConfig>): Promise<boolean>;
    speak(text: string, callback?: Function): Promise<StreamAudioPlayInfo>;
    askCommand(params: AskParams, callback: (msgs: IResultData<string[]>) => void): Promise<void>;
    askStream(params: AskParams, callback: (msgs: Result<ChatMessage$1[]>) => void, options?: {
        skipStop?: boolean;
    }): Promise<Result<AskStreamResponse>>;
    ask(params: AskParams, callback: (result: Result<ChatMessage$1>) => void): Promise<Result<AskResponse>>;
    speakByAudioShapes(uris: string[], shapes: Array<number[][]>): Promise<boolean>;
    speakByAudioStreamShapes(audios: ArrayBuffer[], shapes: number[][], rate?: number): Promise<boolean>;
    speakByAudio(uri: string, shapes: number[][]): Promise<boolean>;
    startVoice2Text(callback?: (data: Voice2TextResult) => void): Promise<IResultData<RecorderPermission>>;
    stopVoice2Text(callback?: (data: Voice2TextResult) => void): Promise<Result<null>>;
    sendToolAction(tool: string, action: string, data: object): void;
    stop(): Promise<boolean>;
    private stopPlayback;
    getStatus(): Status;
    private initStorage;
    muteAudio(isMute?: boolean): void;
    muteAction(isMute?: boolean): void;
    private dealVoice2Text;
    enableAudio(): Promise<void>;
    enableAudioDebug(enabled?: boolean): void;
    getDebugAudioInfo(): {
        sampleRate: number;
        totalSize: number;
        chunks: number;
    };
    downloadDebugAudio(filename?: string): void;
    playDebugAudio(sampleRateOverride?: number): Promise<void>;
    playDebugAudio2(sampleRateOverride?: number, streamMode?: boolean): Promise<void>;
    private playIdleAnimation;
    private finalizeTTSPlayback;
    destroy(): Promise<void>;
    refreshAuthToken(token: string): Promise<void>;
    updateToken(token: string): void;
    setAngleView({ camera }: AngleViewConfig): void;
    playAction(code: string, opts?: PlayActionOptions): Promise<void>;
    getModelInfo(): ModelInfo | null;
    openVoiceInteraction(config: VoiceConfig): Promise<boolean>;
    closeVoiceInteraction(): Promise<boolean>;
    wakeVoiceInteraction(): void;
    sleepVoiceInteraction(): void;
    private createVoiceInteractionWebRTC;
    private handleVoiceInteractionASR;
    private flushPendingASRIfReady;
    private processCompleteASRText;
    private flushMergedText;
    private sendTextToProcess;
    private checkKeywords;
    private containsInterruptIntent;
    private triggerBargeIn;
    private isNoiseText;
    private handleVoiceInteractionWakeup;
    private handleVoiceInteractionSleep;
    private handleVoiceInteractionInterrupt;
    private handleVoiceInteractionAsk;
    private resetVoiceInteractionExitTimer;
    offlineRender(files: CharacterModel[]): Promise<boolean>;
    startRender(): Promise<boolean>;
    stopRender(): Promise<boolean>;
    closeRecorder(): Promise<boolean>;
    openRecorder(): Promise<Result<RecorderPermission>>;
    openCamera(config: CameraConfig): Promise<boolean>;
    startFaceRecognition(config?: FaceRecognitionConfig): Promise<boolean>;
    stopFaceRecognition(): Promise<boolean>;
    startBodyDetect(): Promise<boolean>;
    stopBodyDetect(): Promise<boolean>;
    startSmileDetection(config?: SmileDetectionConfig): Promise<boolean>;
    stopSmileDetection(): boolean;
    closeCamera(): void;
}
//# sourceMappingURL=human.d.ts.map

interface GatewayConfig {
    url: string;
    token: string;
    audioProfile?: 'standard' | 'asr_priority';
    iosAudioMode?: 'baseline' | 'aec' | 'aec_full';
    autoReconnect?: boolean;
    reconnectInterval?: number;
    maxReconnectAttempts?: number;
    heartbeatInterval?: number;
    connectTimeout?: number;
    iceServers?: RTCIceServer[];
    authMethod?: 'url' | 'message';
}
declare enum GatewayState {
    DISCONNECTED = "disconnected",
    CONNECTING = "connecting",
    SOCKET_OPEN = "socket_open",
    AUTHENTICATED = "authenticated",
    CONNECTED = "connected",
    RECONNECTING = "reconnecting",
    CLOSED = "closed"
}
interface LLMChatParams {
    query: string;
    inputs: {
        character_id: string;
        chat_id?: string;
        tts_enabled?: boolean;
        a2f_enabled?: boolean;
        chunk_type?: 'stream' | 'stream_sentence' | 'block';
        use_webrtc_tts?: boolean;
    };
}
interface TTSParams {
    character_id: string;
    text: string;
    a2f_enabled?: boolean;
    use_webrtc_tts?: boolean;
    xf?: number;
    dialect?: string;
    synthetic?: boolean;
}
interface LLMResponseCallback {
    type: 'llm' | 'tts' | 'a2f' | 'end';
    text?: string;
    sampleRate?: number;
    audio?: ArrayBuffer;
    blendShapes?: number[][];
    audioOffset?: number;
    streamId?: string;
    endType?: 'llm' | 'tts' | 'a2f' | 'asr';
}
interface TTSResponseCallback {
    type: 'rate' | 'audio' | 'a2f' | 'end';
    sampleRate?: number;
    audio?: ArrayBuffer;
    blendShapes?: number[][];
    streamId?: string;
    endType?: 'tts' | 'a2f';
}
interface ASRResponseCallback {
    text: string;
    isFinal: boolean;
}
interface WebRTCSDPParams {
    type: 'offer' | 'answer';
    sdp: string;
}
interface WebRTCICEParams {
    candidate: string;
    sdpMid: string;
    sdpMLineIndex: number;
    usernameFragment?: string;
}
interface WebRTCSDPResponseCallback {
    type: 'offer' | 'answer';
    sdp: string;
}
declare class GatewayService {
    private static readonly IOS_AUDIO_MODES;
    private config;
    private ws;
    private state;
    private reconnectAttempts;
    private reconnectTimer;
    private heartbeatTimer;
    private heartbeatPongTimer;
    private isDestroyed;
    private updateTokenWarnedOnce;
    private connectInFlight;
    private lastStateSyncFrame;
    private lastVoiceInteractionConfigFrame;
    private authenticationCount;
    private _sessionId;
    get sessionId(): string;
    private llmCallback;
    private ttsCallback;
    private asrCallback;
    private serverPushTTSCallback;
    private webrtcSDPCallback;
    private webrtcICECallback;
    private currentTTSSampleRate;
    private peerConnection;
    private dataChannel;
    private remoteAudioElement;
    private isWebRTCReady;
    private localAudioTrack;
    private webrtcReconnectAttempts;
    private webrtcReconnectTimer;
    private webrtcASRCallback;
    private isWebRTCReconnecting;
    private isCreatingWebRTC;
    private static readonly WEBRTC_MAX_RECONNECT_ATTEMPTS;
    private static readonly WEBRTC_RECONNECT_INTERVAL;
    private webrtcStatsTimer;
    private lastInboundStats;
    private ttsDataChannelCallback;
    private vadAudioContext;
    private vadAnalyser;
    private vadSourceNode;
    private vadDetectionTimer;
    private vadCallback;
    private vadEnabled;
    private vadEnergyHistory;
    private vadConsecutiveSpikes;
    private vadWarmupComplete;
    private audioLevelCallback;
    private audioLevelTimer;
    private static readonly AUDIO_LEVEL_INTERVAL;
    private static readonly VAD_DETECTION_INTERVAL;
    private static readonly VAD_WINDOW_SIZE;
    private static readonly VAD_SPIKE_THRESHOLD;
    private static readonly VAD_MIN_ABSOLUTE_RMS;
    private static readonly VAD_CONSECUTIVE_SPIKES_REQUIRED;
    private static readonly VAD_MIN_WARMUP_SAMPLES;
    private static readonly VAD_WARMUP_STABILITY_THRESHOLD;
    private ttsDumpEnabled;
    private ttsDumpActive;
    private ttsDumpSampleRate;
    private ttsDumpChunks;
    private ttsDumpTotalBytes;
    private ttsDumpSeq;
    private ttsDumpFinalizeTimer;
    private ttsDumpLastUrl;
    private ttsDumpLastFilename;
    constructor(config: GatewayConfig);
    private resolveIOSAudioMode;
    private buildIOSAudioConstraints;
    connect(): Promise<void>;
    disconnect(): void;
    reconnect(): Promise<void>;
    sendLLMChat(params: LLMChatParams, callback?: (data: LLMResponseCallback) => void): Promise<void>;
    sendToolAction(tool: string, action: string, data: object): void;
    sendTTS(params: TTSParams, callback?: (data: TTSResponseCallback) => void): Promise<void>;
    sendTextToAudio(text: string, characterId: string, options?: {
        useWebRTCTTS?: boolean;
        a2fEnabled?: boolean;
    }): void;
    setServerPushTTSCallback(callback: ((data: TTSResponseCallback) => void) | null): void;
    clearTTSCallback(): void;
    sendASRSync(audioData: ArrayBuffer, callback?: (data: ASRResponseCallback) => void): Promise<void>;
    sendASRAudio(audioData: ArrayBuffer, callback?: (data: ASRResponseCallback) => void): Promise<void>;
    stopASR(): Promise<void>;
    sendWebRTCSDP(params: WebRTCSDPParams, callback?: (data: WebRTCSDPResponseCallback) => void): Promise<void>;
    sendWebRTCICE(params: WebRTCICEParams): Promise<void>;
    createWebRTCConnection(asrCallback?: (data: ASRResponseCallback) => void): Promise<RTCPeerConnection>;
    closeWebRTCConnection(): void;
    private attemptWebRTCReconnect;
    private _muteRefCount;
    muteLocalAudio(): void;
    unmuteLocalAudio(): void;
    forceUnmuteLocalAudio(): void;
    isLocalAudioMuted(): boolean;
    private setupVAD;
    startVADDetection(callback: (detected: boolean, energy: number) => void): void;
    stopVADDetection(): void;
    startAudioLevelMonitor(callback: (level: number) => void): void;
    stopAudioLevelMonitor(): void;
    private cleanupVAD;
    sendWebRTCClose(): Promise<void>;
    sendInterrupt(): Promise<void>;
    sendTTSPlaybackState(event: 'playback_started' | 'playback_ended', context?: 'graceful_exit_prompt' | 'graceful_exit_phase2_prompt'): void;
    sendStateSync(state: 'SLEEPING' | 'IDLE' | 'LISTENING' | 'THINKING' | 'SPEAKING' | 'COOLDOWN'): void;
    sendVoiceInteractionConfig(config: {
        wakeWords: string[];
        syntheticTexts?: string[];
        voiceEngine?: string;
        characterId?: string;
    }): void;
    private replaySessionDirectives;
    setLLMCallback(callback: ((data: LLMResponseCallback) => void) | null): void;
    getState(): GatewayState;
    isConnected(): boolean;
    updateToken(token: string): void;
    refreshAuthToken(token: string): Promise<void>;
    destroy(): void;
    private buildWebSocketUrl;
    private sendLogin;
    private handleMessage;
    private handleLLMResponse;
    private handleTTSSampleRate;
    private handleTTSAudio;
    private handleTTSAudioSequence;
    private handleASRResponse;
    private handleA2FResponse;
    private handleA2FResponseSequence;
    private handleEndMarker;
    private startTtsDump;
    private appendTtsDump;
    private scheduleFinalizeTtsDump;
    private finalizeTtsDump;
    private encodeWavPcm16;
    private handleCharacterAction;
    private handleWebRTCSDPResponse;
    private handleWebRTCICEResponse;
    private handleWebRTCAnswer;
    private handleWebRTCICE;
    private handleWebRTCReady;
    private handleWebRTCClose;
    isWebRTCConnected(): boolean;
    getRemoteAudioElement(): HTMLAudioElement | null;
    resumeRemoteAudio(): void;
    setTTSDataChannelCallback(callback: ((audio: ArrayBuffer) => void) | null): void;
    setRemoteAudioMuted(muted: boolean): void;
    isTTSDataChannelReady(): boolean;
    startWebRTCStatsMonitoring(): void;
    stopWebRTCStatsMonitoring(): void;
    getWebRTCStats(): Promise<{
        packetsReceived: number;
        bytesReceived: number;
        packetsLost: number;
        jitter: number;
        roundTripTime: number;
    } | null>;
    private static readonly GRPC_CANCEL_PATTERNS;
    private handleSystemError;
    private handleLoginError;
    private handleBalanceError;
    private handleError;
    private handleClose;
    private scheduleReconnect;
    private stopReconnect;
    private startHeartbeat;
    private stopHeartbeat;
    private sendHeartbeat;
    private setState;
}

type VoiceState$1 = 'SLEEPING' | 'IDLE' | 'LISTENING' | 'THINKING' | 'SPEAKING' | 'COOLDOWN';
type TTSPlaybackContext = 'graceful_exit_prompt' | 'graceful_exit_phase2_prompt';
interface VoiceError$1 {
    code: 'WEBRTC_FAILED' | 'ASR_ERROR' | 'LLM_TIMEOUT' | 'LLM_ERROR' | 'TTS_FAILED' | 'GATEWAY_DISCONNECTED';
    message: string;
    recoverable: boolean;
}
interface VoiceConversationEvents {
    stateChange: {
        state: VoiceState$1;
        prevState: VoiceState$1;
    };
    wakeUp: {
        trigger: 'word' | 'manual';
        word?: string;
    };
    sleep: {
        trigger: 'word' | 'timeout' | 'manual' | 'server';
    };
    bargeIn: {
        text: string;
        type?: 'supplement' | 'interrupt';
    };
    transcript: {
        text: string;
        isFinal: boolean;
    };
    response: {
        text: string;
    };
    speaking: {
        text: string;
    };
    speakEnd: void;
    error: VoiceError$1;
    webrtcReady: void;
    webrtcReconnecting: {
        attempt: number;
        maxAttempts: number;
    };
    interruptHintShow: {
        words: string[];
    };
    interruptHintHide: void;
    interrupted: {
        text: string;
        feedback: string;
        vad?: boolean;
    };
    postExitIdle: void;
    wakeConfirm: {
        text: string;
    };
}
interface VoiceConversationConfig {
    gateway: GatewayService;
    renderer: any;
    framePlayer: FramePlayer;
    characterId: string;
    wakeWords?: string[];
    exitWords?: string[];
    interruptWords?: string[];
    idleTimeout?: number;
    silenceTimeout?: number;
    autoWake?: boolean;
    echoDetection?: boolean;
    ttsTransport?: 'auto' | 'webrtc' | 'websocket';
    voiceEngine?: 'pipeline' | 'doubao_pipeline' | 'doubao_e2e';
    bargeInSensitivity?: 'high' | 'medium' | 'low';
    interruptAck?: 'none' | 'short';
    interruptFeedback?: string;
    welcomeAsrResumeDelayMs?: number;
    enableInterrupt?: boolean;
    cooldownDuration?: number;
    doubleWakeWord?: boolean;
    wakeConfirmText?: string;
    syntheticTexts?: string[];
    gracefulExitEnabled?: boolean;
    gracefulExitPrompt?: string;
    gracefulExitPhase2Prompt?: string;
    gracefulExitPhase2Silence?: number;
    gracefulExitPhase3Silence?: number;
    bargeInStrictMode?: boolean;
    continuousWindowMs?: number;
    bargeInCooldownMs?: number;
    llmTimeoutMs?: number;
    llmMaxRetry?: number;
    webrtcMaxReconnectAttempts?: number;
    webrtcReconnectInterval?: number;
    vadGateWindowMs?: number;
    vadGraceMs?: number;
    interruptFollowUpWindowMs?: number;
    interruptWordFilterMs?: number;
    animations?: {
        wake?: string;
        idle?: string;
        talk?: string | string[];
    };
    onStateChange?: (state: VoiceState$1, prevState: VoiceState$1) => void;
    onTranscript?: (text: string, isFinal: boolean) => void;
    onResponse?: (text: string) => void;
    onError?: (error: VoiceError$1) => void;
}
interface InternalConfig extends Required<Omit<VoiceConversationConfig, 'onStateChange' | 'onTranscript' | 'onResponse' | 'onError' | 'animations' | 'interruptAck' | 'interruptFeedback' | 'enableInterrupt' | 'cooldownDuration' | 'doubleWakeWord' | 'wakeConfirmText' | 'syntheticTexts' | 'gracefulExitEnabled' | 'gracefulExitPrompt' | 'gracefulExitPhase2Prompt' | 'gracefulExitPhase2Silence' | 'gracefulExitPhase3Silence' | 'bargeInStrictMode' | 'continuousWindowMs' | 'ttsTransport' | 'voiceEngine' | 'bargeInCooldownMs' | 'llmTimeoutMs' | 'llmMaxRetry' | 'webrtcMaxReconnectAttempts' | 'webrtcReconnectInterval' | 'vadGateWindowMs' | 'vadGraceMs' | 'interruptFollowUpWindowMs' | 'interruptWordFilterMs'>> {
    onStateChange?: (state: VoiceState$1, prevState: VoiceState$1) => void;
    onTranscript?: (text: string, isFinal: boolean) => void;
    onResponse?: (text: string) => void;
    onError?: (error: VoiceError$1) => void;
    animations: {
        wake?: string;
        idle: string;
        talk: string | string[];
    };
    interruptAck?: 'none' | 'short';
    interruptFeedback?: string;
    enableInterrupt: boolean;
    doubleWakeWord: boolean;
    wakeConfirmText?: string;
    syntheticTexts: string[];
    gracefulExitEnabled: boolean;
    gracefulExitPrompt: string;
    gracefulExitPhase2Prompt: string;
    gracefulExitPhase2Silence: number;
    gracefulExitPhase3Silence: number;
    bargeInStrictMode: boolean;
    continuousWindowMs?: number;
    ttsTransport: 'auto' | 'webrtc' | 'websocket';
    voiceEngine: 'pipeline' | 'doubao_pipeline' | 'doubao_e2e';
    bargeInCooldownMs: number;
    llmTimeoutMs: number;
    llmMaxRetry: number;
    webrtcMaxReconnectAttempts: number;
    webrtcReconnectInterval: number;
    vadGateWindowMs: number;
    vadGraceMs: number;
    interruptFollowUpWindowMs: number;
    interruptWordFilterMs: number;
}
declare class VoiceConversation extends Emittery {
    private _config;
    private _state;
    private _conversationId;
    private _isStarted;
    private isTransitioning;
    private pendingTransition;
    private textBuffer;
    private committedTranscript;
    private silenceTimer;
    private idleTimer;
    private currentRequestId;
    private activeLLMRequestId;
    private activeLLMResolve;
    private activeLLMReject;
    private activeLLMTimeout;
    private ttsStartTime;
    private lastBargeInTime;
    private speakingTextBuffer;
    private lastUserQuery;
    private static readonly CONTINUATION_WINDOW_MS;
    private static readonly BARGE_IN_MIN_TEXT_LENGTH;
    private static readonly DEFAULT_BARGE_IN_COOLDOWN_MS;
    private static readonly DEFAULT_WELCOME_ASR_RESUME_DELAY_MS;
    private interruptDetectionTimer;
    private interruptHintTimer;
    private interruptFollowUpTimer;
    private welcomeAsrResumeTimer;
    private interruptDetectionEnabled;
    private vadGateTimer;
    private vadGateActiveUntil;
    private vadGateEnabled;
    private lastVadTriggerTime;
    private static readonly DEFAULT_VAD_GATE_WINDOW_MS;
    private static readonly VAD_DUCK_GAIN;
    private static readonly VAD_DUCK_MS;
    private static readonly DEFAULT_VAD_GRACE_MS;
    private static readonly VAD_START_DELAY_MS;
    private static readonly DEFAULT_INTERRUPT_FOLLOW_UP_WINDOW_MS;
    private static readonly CORE_INTERRUPT_WORDS;
    private isPlayingWelcomeTTS;
    private currentPlaybackContext;
    private allowFollowUpDuringPlayback;
    private gracefulExitFollowUpBuffer;
    private isPlayingInterruptFeedback;
    private isHandlingInterrupt;
    private lastInterruptTime;
    private static readonly DEFAULT_INTERRUPT_WORD_FILTER_MS;
    private isPlayingTTSLocked;
    private dataChannelEndTimer;
    private vadStartTimer;
    private webrtcReconnectAttempts;
    private webrtcReconnectTimer;
    private llmRetryCount;
    private _isReconnecting;
    private llmRequestCancelled;
    private _asrSuspended;
    private ttsEndTimestampForASRDiag;
    private static readonly DEFAULT_MAX_WEBRTC_RECONNECT_ATTEMPTS;
    private static readonly DEFAULT_WEBRTC_RECONNECT_INTERVAL;
    private static readonly DEFAULT_MAX_LLM_RETRY_COUNT;
    private static readonly DEFAULT_LLM_TIMEOUT_MS;
    private echoDetector;
    private ttsTimeline;
    private llmDataEnded;
    private ttsDataEnded;
    private a2fDataEnded;
    private webrtcAudioClockBound;
    private currentA2fStreamId;
    private lastA2fOffset;
    private a2fOffsetBase;
    private ttsPlaybackState;
    private activeTTSTransport;
    private llmTTSStreamPrepared;
    private static readonly DEFAULT_WAKE_WORDS;
    private static readonly DEFAULT_EXIT_WORDS;
    private static readonly DEFAULT_INTERRUPT_WORDS;
    private static readonly SUPPLEMENT_WORDS;
    private static readonly HARD_INTERRUPT_WORDS;
    private static readonly DEFAULT_IDLE_TIMEOUT;
    private static readonly DEFAULT_SILENCE_TIMEOUT;
    private static readonly DEFAULT_GRACEFUL_EXIT_PROMPT;
    private static readonly DEFAULT_GRACEFUL_EXIT_PHASE2_PROMPT;
    private static readonly DEFAULT_GRACEFUL_EXIT_PHASE2_SILENCE;
    private static readonly DEFAULT_GRACEFUL_EXIT_PHASE3_SILENCE;
    private exitPromptTimer;
    private isInPostExitIdle;
    private pendingPostExitIdleEmit;
    private gracefulExitGeneration;
    private gracefulExitPhase;
    private effectiveInterruptWords;
    private configuredInterruptWords;
    constructor(config: VoiceConversationConfig);
    private resolveEnableInterrupt;
    get state(): VoiceState$1;
    get config(): Readonly<InternalConfig>;
    get coreInterruptWords(): readonly string[];
    get isStarted(): boolean;
    get isReconnecting(): boolean;
    get conversationId(): string;
    start(): Promise<void>;
    stop(): Promise<void>;
    wake(): void;
    sleep(): void;
    suspendASR(): void;
    resumeASR(): void;
    private isGracefulExitPromptContext;
    private shouldCaptureGracefulExitFollowUp;
    private bufferGracefulExitFollowUp;
    private flushGracefulExitFollowUpBuffer;
    get isASRSuspended(): boolean;
    sendText(text: string): Promise<void>;
    playTTS(text: string, options?: {
        dialect?: string;
        synthetic?: boolean;
        playbackContext?: TTSPlaybackContext;
        allowFollowUpDuringPlayback?: boolean;
    }): Promise<void>;
    private transitionTo;
    private syncStateToGateway;
    private onEnterState;
    private handleASRResult;
    private processASRText;
    private clearTranscriptDisplay;
    private handleASRInSleeping;
    private _isSameUtterance;
    private _isWakeWordOnly;
    private handleASRInIdle;
    private handleASRInListening;
    private handleASRInThinking;
    private handleVoiceInterrupt;
    private playInterruptFeedback;
    private getBargeInThresholds;
    private shouldTriggerBargeIn;
    private handleBargeIn;
    private handleBargeInTransition;
    private classifyBargeIn;
    private sendToLLM;
    private sendToLLMWithRetry;
    private isRetryableError;
    private handleLLMResponse;
    private checkAllDataEnded;
    private resetDataEndedFlags;
    private registerEventListeners;
    private unregisterEventListeners;
    private handleGatewayStatePush;
    private getRandomTalkAnimation;
    private handleTTSPlayStart;
    private enableInterruptDetection;
    private handleVADDirectInterrupt;
    private openVadGate;
    private isVadGateOpen;
    private isVadRecent;
    private matchExplicitInterruptPhrase;
    private hasExplicitInterruptIntent;
    private hasWakeWordInterrupt;
    private clearInterruptTimers;
    private startInterruptFollowUpWindow;
    private clearInterruptFollowUpWindow;
    private handleTTSPlayEnd;
    private scheduleWelcomeASRResume;
    private clearWelcomeAsrResumeTimer;
    private handleAudioPlaybackStart;
    private handleAnimationEnd;
    private handleGatewayDisconnect;
    private handleGatewayReconnecting;
    private handleWebRTCStateChange;
    private attemptWebRTCReconnect;
    private clearWebRTCReconnectTimer;
    private _expandedWakeWords;
    private sendExpandedWakeWords;
    private handleSleep;
    private handleInterrupt;
    private shouldAllowShortFollowUp;
    private shouldUseWebRTCTTS;
    private bindActiveLLMRequest;
    private clearActiveLLMTimeout;
    private clearActiveLLMRequest;
    private resolveActiveLLMRequest;
    private cancelActiveLLMRequest;
    private startSilenceTimer;
    private clearSilenceTimer;
    private flushTextBuffer;
    private resetIdleTimer;
    private handleGracefulExitPhase1;
    private handleGracefulExitPhase2;
    private waitForGracefulExitPlayEnd;
    private clearIdleTimer;
    private generateRequestId;
    private emitError;
}

type VoiceState = 'SLEEPING' | 'IDLE' | 'LISTENING' | 'THINKING' | 'SPEAKING';
interface VoiceError {
    code: 'WEBRTC_FAILED' | 'ASR_ERROR' | 'LLM_TIMEOUT' | 'LLM_ERROR' | 'TTS_FAILED' | 'GATEWAY_DISCONNECTED';
    message: string;
    recoverable: boolean;
}
interface VoiceConversationE2EConfig {
    gateway: GatewayService;
    renderer: any;
    framePlayer: FramePlayer;
    characterId: string;
    wakeWords?: string[];
    exitWords?: string[];
    interruptWords?: string[];
    idleTimeout?: number;
    autoWake?: boolean;
    echoDetection?: boolean;
    doubleWakeWord?: boolean;
    bargeInStrictMode?: boolean;
    continuousWindowMs?: number;
    gracefulExitEnabled?: boolean;
    gracefulExitPrompt?: string;
    animations?: {
        wake?: string;
        idle: string;
        talk: string | string[];
    };
    onStateChange?: (state: VoiceState, prevState: VoiceState) => void;
    onTranscript?: (text: string, isFinal: boolean) => void;
    onResponse?: (text: string) => void;
    onError?: (error: VoiceError) => void;
}
declare class VoiceConversationE2E extends Emittery {
    private _config;
    private _state;
    private _conversationId;
    private _isStarted;
    private isTransitioning;
    private pendingTransition;
    private textBuffer;
    private lastTranscript;
    private llmResponseText;
    private echoDetector;
    private effectiveWakeWords;
    private effectiveInterruptWords;
    private idleTimer;
    private gracefulExitPhase;
    private ttsDataEnded;
    private isReceivingTTSAudio;
    private wakeTimestamp;
    private ttsEndTimestamp;
    private boundHandleTTSPlayStart;
    private boundHandleTTSPlayEnd;
    constructor(config: VoiceConversationE2EConfig);
    getState(): VoiceState;
    isStarted(): boolean;
    start(): Promise<void>;
    stop(): Promise<void>;
    destroy(): void;
    wake(): void;
    sleep(): void;
    sendText(_text: string): Promise<void>;
    private handleASRResult;
    private handleASRInSleeping;
    private handleASRInIdle;
    private handleASRInListening;
    private handleListeningFinal;
    private handleASRInSpeaking;
    private handleLLMResponse;
    private handleTTSPlayStart;
    private handleTTSPlayEnd;
    private handleInterrupt;
    private handleSleep;
    private startIdleTimer;
    private clearIdleTimer;
    private transitionTo;
    private onEnterState;
}

declare function generateNameVariants(name: string): string[];
declare function buildExpandedWakeWords(wakeWords: string[], options?: {
    doubleWakeWord?: boolean;
    interruptWords?: string[];
}): string[];

interface InterruptHintConfig {
    container: string | HTMLElement;
    conversation: VoiceConversation;
    textPrefix?: string;
    textSuffix?: string;
    animationDuration?: number;
    customStyles?: Partial<CSSStyleDeclaration>;
}
declare class InterruptHint {
    private container;
    private conversation;
    private hintElement;
    private config;
    private isVisible;
    private handleShow;
    private handleHide;
    private handleInterrupted;
    constructor(config: InterruptHintConfig);
    private registerEventListeners;
    private unregisterEventListeners;
    private createHintElement;
    private show;
    private hide;
    private onInterrupted;
    private showFeedback;
    get visible(): boolean;
    forceShow(words?: string[]): void;
    forceHide(): void;
    destroy(): void;
}
//# sourceMappingURL=interruptHint.d.ts.map

//# sourceMappingURL=index.d.ts.map

export { type ASRRequest, type ASRRequestData, type ASRResponse, type ASRResponseData, type AmbientLight, type AngleViewConfig, type AnimationClip, type AnimationEvent, type AskCallback, type AskError, type AskParams, type AskResponse, type AskStreamResponse, type AudioConfig, type AudioPlayEvent, type Body, type BodyOption, type Bone, type Camera, type CameraConfig, type CameraCore, type CameraFeature, type Character, type CharacterActionEvent, type CharacterInfo, type CharacterModel, type ChatFile, type ChatMessage$1 as ChatMessage, type ChatFile as ChatMessageFile, type ChatMessageParams, type ChatResponseMode as ChatMessageResonseMode, type ChatRequest, type ChatRequestData, type ChatResponse, type ChatResponseData, type ChatResponseMode, type HumanConfig as Configuration, type DirectionalLight, EmitEvent, type ErrorEvent, type ErrorResponse, type EventListener, type EventMap, type FaceRecognitionConfig, type FaceRecognitionResult, type FacingMode, type GatewayConfig$1 as GatewayConfig, type GatewayMessageEvent, type GatewayMessageType, type GatewayRequest, type GatewayRequestBase, type GatewayResponse, type GatewayResponseBase, GatewayService, GatewayState, type TTSResponse as GatewayTTSResponse, type Geometry, type Group, type HeartbeatRequest, type HeartbeatResponse, type HemisphereLight, type IHuman as Human, type HumanConfig, type HumanConstructor, type HumanConstructorParams, type IHuman, type IOSAudioMode, type Result as IResult, type Result as IResultData, type Image, InterruptHint, type Light, type Line, type LoadProgressEvent, type LoaderProgress, type LoaderResponse, type Message as MSG, type Mat4, type Material, type Matrix4, type Mesh, type Message, type MessageRole, type Mode, type ModelDescription, type ModelFile, type ModelInfo, type ModelLoadEvent, type Object3D, type Object3DBase, type OrthographicCamera, type RecorderPermission as PermissionResult, type PersonDetectionResult, type PerspectiveCamera, type PlayActionOptions, type PlayInfo, type PointLight, type Points, type LoaderProgress as Progress, type RecorderPermission, type RectAreaLight, type RenderConfig, type ResolvedAssetConfig, type ResolvedAssetSceneConfig, type ResolvedBehaviorConfig, type ResolvedCharacterConfig, type ResolvedRenderConfig, type Result, type Scene, type SceneConfig, type SceneType, type ServerConfig, type SpeakCallback, type SpotLight, type Sprite, type Status, type StreamAudioPlayInfo, type TCamera, type TTSModel, type TTSParams$1 as TTSParams, type TTSRequest, type TTSRequestData, type TTSResponse$1 as TTSResponse, type TTSResponseData, type TTSRole, type TTSViseme, type TTSModel as TTS_MODEL, type TTSRole as TTS_ROLE, type TTSViseme as TTS_VISEME, type TTSResponse$1 as Text2Speech, type TTSParams$1 as Text2SpeechParams, type Texture, type ThreeJSON, type Vec2, type Vec3, type Vec4, type Voice2TextResult as Voice2Text, type Voice2TextCallback, type Voice2TextEvent, type Voice2TextResult, type VoiceConfig, VoiceConversation, type VoiceConversationConfig, VoiceConversationE2E, type VoiceConversationE2EConfig, type VoiceConversationEvents, type VoiceError$1 as VoiceError, type VoiceModeConfig, type VoiceState$1 as VoiceState, WebSocketState, type XYZ, buildExpandedWakeWords, Human as default, generateNameVariants };
