/**
 * DigitalHumanFrame — Renders a DigitalHuman avatar inside an iframe (via srcdoc),
 * exposing the same public API as DigitalHuman. AI tool calls inside the iframe
 * are automatically delegated to the parent frame's AIChatSession via AgentRouter
 * and the SandboxToolEnv toolProxy mechanism.
 *
 * Why iframe?
 *   - Process isolation: Live2D / heavy video rendering won't block the parent page.
 *   - Style isolation: Avatar CSS and PIXI globals don't leak into the host page.
 *   - Easy teardown: destroying the iframe reclaims all resources.
 *
 * Architecture (AgentRouter based tool delegation):
 *   1. Parent creates a local proxy session for resolving tool calls and registers it
 *      with the AgentRouter as \`parentToolAgent_\${frameId}\`.
 *   2. Iframe runs a full KeepworkSDK and owns the REAL AI Session.
 *   3. Iframe configures its session with a \`toolProxy\` that maps all
 *      tool categories to the \`parentToolAgent_\${frameId}\` agent.
 *   4. When the Iframe AI wants to call a tool (e.g. \`read_file\`), the iframe's
 *      SandboxToolEnv intercepts it and uses AgentRouter.submitTask({ toolCallOnly: true })
 *      to send the execution command to the Parent.
 *   5. Parent's AgentRouter receives it, maps it to the local proxy session,
 *      which then delegates back to the Parent's real \`sdk.copilotTools.execute()\`.
 *
 * Usage:
 *   const dhf = new DigitalHumanFrame({ sdk, container: document.getElementById('avatar-root') });
 *   await dhf.initFromConfig(config);       // same config as DigitalHuman, including textToSpeech.autoReadReply
 *   dhf.on('message', ({ partialText }) => { ... });
 *   await dhf.send('Hello');
 *   dhf.playAction('happy', 5);
 */
type DHFAny = Record<string, any>;
export default class DigitalHumanFrame {
    sdk: DHFAny;
    container: HTMLElement;
    workspace: unknown;
    frameId: string;
    parentToolAgentName: string;
    characterConfig: DHFAny | null;
    characterInfo: DHFAny | null;
    voiceChatConfig: DHFAny;
    _iframe: HTMLIFrameElement | null;
    _pendingCalls: Map<string, DHFAny>;
    _commands: Record<string, DHFAny>;
    [key: string]: any;
    /**
     * @param {Object} options
     * @param {Object} options.sdk - KeepworkSDK instance (used for tool execution on parent side)
     * @param {HTMLElement} options.container - Container element for the iframe
     * @param {string} [options.sdkSrc] - URL to keepworkSDK.iife.js
     * @param {boolean} [options.useLocalSdk] - Set to true if sdkSrc is a local ES module instead of IIFE bundle
     */
    constructor({ sdk, container, sdkSrc, useLocalSdk, useExternalHtml, workspace, proxyCategories, subtitle }?: DHFAny);
    get on(): any;
    get off(): any;
    get emit(): any;
    /**
     * Auto-register the `minigame` copilot tool category on the PARENT SDK and
     * subscribe this frame to iframe events. Because the inner DigitalHuman
     * proxies all LLM tool calls to the parent via AgentRouter, the minigame
     * overlay is always created in the containing window (not inside the
     * iframe). Default `gameFinished` handling:
     *   1. Emit `minigameEvent` for host integrations.
     *   2. Call `this.restartAgent()` so the inner DH picks up workspace changes.
     * Disable step 2 via characterConfig.minigame.autoRestartAgent = false.
     */
    _registerMinigameTool(): void;
    launchSkill(promptFile?: string, options?: DHFAny): Promise<{
        ok: boolean;
        slot: any;
        restart: DHFAny;
        session: any;
    }>;
    preloadSkill(promptFile?: DHFAny, options?: DHFAny): Promise<{
        ok: boolean;
        slot: any;
        restart: DHFAny;
        session: any;
        preloaded: boolean;
    }>;
    showPreloadedSkill(options?: DHFAny): Promise<{
        ok: boolean;
        reason: string;
        slot?: undefined;
        session?: undefined;
    } | {
        ok: boolean;
        slot: any;
        session: any;
        reason: string;
    } | {
        ok: boolean;
        slot: any;
        session: any;
        reason?: undefined;
    }>;
    _handleLaunchedMinigameClosed(data: DHFAny, launchSession: DHFAny): Promise<void>;
    _formatMinigameResult(data?: DHFAny, session?: DHFAny): string;
    _createProxySession(): void;
    _registerDigitalHumanProxyAPIs(): void;
    _destroyProxySession(): void;
    /**
     * Close a minigame iframe overlay (if open) and optionally restart the agent.
     * @param {Object} [options]
     * @param {string} [options.slot] - Slot to close. Defaults to active slot.
     * @param {string} [options.reason='user'] - Close reason passed to MinigameTools.close()
     * @param {boolean} [options.restartAgent=true] - Whether to restart the agent after closing
     * @returns {Promise<void>}
     */
    closeMinigame(options?: DHFAny): Promise<void>;
    /** Forward user ASR subtitles from the DigitalHuman iframe into the active minigame. */
    _forwardUserVoiceInputToMinigame(data?: DHFAny): void;
    _forwardAssistantSpeakingToMinigame(data?: DHFAny): void;
    /**
     * Inject parent tool definitions and proxy category list into a config
     * before sending it to the iframe. The iframe's setupToolProxy reads these
     * to register unknown categories and build the proxy map dynamically.
     * @param {Object} config - The session/init config (mutated in place)
     */
    _injectParentToolInfo(config: DHFAny): void;
    /** Create and inject the iframe into the container. */
    _ensureIframe(): any;
    /**
     * Send a command to the iframe and wait for a response.
     * @param {string} type - Message type
     * @param {Object} [payload] - Additional payload fields
     * @returns {Promise<Object>} The response result
     */
    _rpc(type: string, payload?: DHFAny): Promise<DHFAny>;
    /** Send a fire-and-forget command to the iframe (no response expected). */
    _post(type: string, payload?: DHFAny): void;
    _handleMessage(e: MessageEvent): void;
    /**
     * Handle an external send message. Optionally interrupts, then forwards
     * to the iframe via the SEND RPC.
     * @private
     * @param {Object} msg - { type: 'dh:send', text: string, interrupt?: boolean, options?: object }
     */
    _handleExternalSend(msg: DHFAny): Promise<void>;
    /**
     * Handle an external context message. Sends context to the iframe and
     * optionally starts a debounce timer for auto-flush.
     * @private
     */
    _handleExternalContext(msg: DHFAny): void;
    /** @private */
    _autoFlushExternalContext(): Promise<void>;
    /** @private */
    _sendCurrentPageRouterWakeupIfNeeded(): Promise<boolean>;
    /**
     * Wait for the inner voice agent to become ready by listening for the
     * first `voiceChatState` event relayed from the iframe.
     * @private
     * @param {number} [timeout=8000]
     * @returns {Promise<boolean>}
     */
    _waitForVoiceReady(timeout?: number): Promise<unknown>;
    /** @private */
    _startPageRouterHeartbeat(page: string, routerEntry: DHFAny): void;
    /**
     * Handle an AppPageOpened message. Forwards to the iframe DigitalHuman
     * which owns the pageRouters config and handles agent switching.
     * @private
     * @param {Object} msg - { type: 'dh:app-page-opened', page: string }
     */
    _handleAppPageOpened(msg: DHFAny): Promise<void>;
    /**
     * Register a slash command intercepted by send().
     * @param {string} name - Command name (without /)
     * @param {Object} def
     * @param {string} def.description - Short help text
     * @param {boolean} [def.needsArg=true] - Whether the command requires an argument
     * @param {function(string, DigitalHumanFrame):void|Promise<void>} def.handler
     */
    registerCommand(name: string, { description, needsArg, handler }: DHFAny): void;
    unregisterCommand(name: string): void;
    listCommands(): {
        name: string;
        description: any;
        needsArg: any;
    }[];
    tryCommand(text: string): {
        handled: boolean;
        name?: undefined;
        error?: undefined;
        result?: undefined;
    } | {
        handled: boolean;
        name: string;
        error: string;
        result?: undefined;
    } | {
        handled: boolean;
        name: string;
        result: any;
        error?: undefined;
    };
    initAvatar(videoActions: DHFAny, options?: DHFAny): Promise<void>;
    /**
     * Shared pre-processing for configs sent to the iframe: sync workspace/mountFolder
     * to the parent proxy session, inject parent tool info, and pre-resolve
     * summarizeAgent.config URLs.
     * @param {Object} config - Mutated in place
     */
    _prepareConfigForIframe(config: DHFAny): Promise<void>;
    initFromConfig(config?: DHFAny): Promise<{
        session: any;
        config: any;
        character: any;
        initial_message: any;
        quick_replies: any;
        objective: any;
        completion_messages: any;
        voiceChat: any;
    }>;
    /**
     * Load a DigitalHuman config from a URL (JSON / YML / MD), inline JSON string, or object,
     * then initialize the iframe avatar and AI session in one call.
     *
     * The config is fetched and parsed on the parent side (using DigitalHuman.fetchConfig),
     * then passed to the iframe via the existing initFromConfig RPC.
     *
     * @param {string|Object} source - URL string, JSON string, or config object
     * @returns {Promise<Object>} Result of initFromConfig
     */
    loadConfig(source: DHFAny): Promise<{
        session: any;
        config: any;
        character: any;
        initial_message: any;
        quick_replies: any;
        objective: any;
        completion_messages: any;
        voiceChat: any;
    }>;
    createSession(config?: DHFAny): Promise<any>;
    /**
     * Get the current session (parent-side proxy).
     * @returns {Object|null}
     */
    getSession(): any;
    /**
     * Unified send — mirrors DigitalHuman.send().
      * Pass options.autoReadReply=false to suppress automatic text-mode reply playback.
     */
    send(userMessage: string, options?: DHFAny): Promise<any>;
    /**
     * Send a message via the inner text AI session.
     */
    sendMessage(userMessage: string, options?: DHFAny): Promise<any>;
    /**
     * Cancel any active/queued text sends (aborts in-flight LLM requests and stops TTS).
     * Useful for barge-in scenarios where a new user utterance should immediately
     * supersede the current response.
     * @param {string} [reason='barge-in'] - Reason label for logging/debugging
     * @returns {Promise<{canceledCount: number}>}
     */
    cancelSend(reason?: string): Promise<any>;
    /**
     * Expand an inline system prompt inside the iframe's own DigitalHuman session.
     * This avoids resolving ${...} against the parent proxy sandbox.
     * @param {string} text
     * @returns {Promise<string>}
     */
    expandInlineSystemPrompt(text: string): Promise<any>;
    /**
     * Send the configured boot message explicitly after the caller finishes
     * restoring any prior history into the UI.
     */
    sendBootMessage(bootMessage: string, options?: DHFAny): Promise<any>;
    /**
     * Immediately send heartbeat text in the inner DigitalHuman. If text is omitted,
     * the inner DigitalHuman uses the current page router heartbeatText, then
     * falls back to "[heartbeat]".
     * @param {string} [text]
     * @param {Object} [options] - send() options forwarded to DigitalHuman.
     * @returns {Promise<Object>}
     */
    sendHeartbeat(text: string, options?: DHFAny): Promise<any>;
    /**
     * Trigger the voice heartbeat path immediately from the host app.
     * This uses the same RTC voice guards and event stream as automatic
     * silence heartbeat, but the app provides the current business context.
     * @param {string|Object} input - Explicit heartbeat text, or { text, reason, context, data }.
     * @param {Object} [options] - Heartbeat options forwarded to DigitalHuman.
     * @returns {Promise<Object>}
     */
    triggerVoiceHeartbeat(input?: {}, options?: DHFAny): Promise<any>;
    /**
     * Set whether the framed DigitalHuman is actively listening/speaking.
     * This does not switch text/voice mode.
     * @param {boolean} active
     * @param {Object} [options]
     * @returns {Promise<Object>}
     */
    setActive(active?: boolean, options?: DHFAny): Promise<DHFAny>;
    get isActive(): any;
    playAction(actionKey: string, duration?: number): void;
    switchVideo(type: string): void;
    switchToIdle(): void;
    switchToTalking(): void;
    setMouthOpen(value: number): void;
    playMotion(preferredGroups: DHFAny, priority?: number): void;
    getActions(): Promise<any>;
    getActionList(lang?: string): Promise<any>;
    getAvatarStatus(): Promise<any>;
    getSessionData(): Promise<any>;
    startVoiceChat(preset?: {}, options?: DHFAny): Promise<void>;
    stopVoiceChat(): Promise<void>;
    setSubtitleConfig(config?: DHFAny): Promise<any>;
    getSubtitleConfig(): Promise<any>;
    clearSubtitle(options?: DHFAny): Promise<DHFAny>;
    /**
     * Update an active voice chat session (REST API proxy).
     * @param {string} command - e.g. 'ExternalTextToSpeech', 'UpdateParameters', 'interrupt'
     * @param {Object} [options] - Additional fields (Message, InterruptMode, Parameters, etc.)
     * @returns {Promise<Object>}
     */
    updateVoiceChat(command: string, options?: DHFAny): Promise<DHFAny>;
    /**
     * Restart voice chat with optional config overrides (deep-merged into the last preset).
     * @param {Object} [configOverrides] - Partial preset overrides
     * @returns {Promise<Object>}
     */
    restartVoiceChat(configOverrides?: DHFAny): Promise<DHFAny>;
    /** @private */
    _cancelRestartAgentDebounce(result?: DHFAny): boolean;
    /**
     * Restart the agent session with an optional prompt file.
     * Delegates to the iframe's DigitalHuman.restartAgent() via RPC.
     * @param {string} [promptFile] - URL or path to agent config file
     * @param {string[]} [tools] - Optional tool category override. Empty means inherit defaults.
     * @param {Object} [options]
    * @param {number} [options.debounceMs=0] - Delay empty-prompt restarts; cancelled by any later explicit prompt restart.
    * @param {boolean} [options.autoContinue=true] - Automatically send "(continue)" after a prompt-file restart.
     * @returns {Promise<Object>} { configSource, mode }
     */
    restartAgent(promptFile?: string, tools?: DHFAny, options?: DHFAny): Promise<DHFAny>;
    handleAuthStateChange(change?: DHFAny): Promise<any>;
    reloadForAuthChange(change?: DHFAny): Promise<any>;
    /**
     * Tear down the iframe, proxy session, registered search paths and pending RPCs.
     * Shared by destroy() and reloadForAuthChange(). Does NOT remove outer-instance
     * listeners (window message, auth, minigame, audio resume) since the DHF
     * instance may continue living after a reload.
     * @private
     * @param {string} [pendingRejectReason]
     */
    _tearDownIframe(pendingRejectReason?: string): Promise<void>;
    sendText(text: string): void;
    sendVoiceText(text: string): void;
    /**
     * Send background context to the voice chat LLM via WebSocket (binary channel).
     * Does not trigger a reply — injected as context for the next response.
     * @param {string} text - Context text
     * @param {Object} [options]
     * @param {boolean} [options.insertToHistory=false] - Also persist as a Q/A pair in history
     */
    sendContext(text: string, options?: DHFAny): void;
    /**
     * Send text to the agent's TTS (text-to-speech) via the iframe voice chat session.
     * @param {string} text
     * @param {Object} [options]
     * @param {boolean} [options.useREST=false] - Use REST API instead of binary channel
     * @param {number} [options.interruptMode] - REST only: interrupt priority
     */
    sendTTS(text: string, options?: DHFAny): void;
    /**
     * Load a dedicated summarize agent config.
     * The config is fetched on the parent side and sent to the iframe DigitalHuman.
     * @param {string|Object} source - Config URL, JSON string, or config object
     * @returns {Promise<void>}
     */
    loadSummarizeAgentConfig(source: DHFAny): Promise<void>;
    /**
     * Trigger conversation summarization in the iframe DigitalHuman.
     * Returns immediately. Only one summarization runs at a time; subsequent
     * calls are queued and merged so the latest options win.
     * Listen for the 'summarized' event to receive the result.
     * @param {Object} [options]
     * @param {number} [options.keepRecentRounds] - Recent pairs to preserve
     * @param {string} [options.mode] - 'replace' or 'append'
     */
    summarize(options?: DHFAny): void;
    /** @private Called when the iframe emits a 'summarized' event to drain the queue. */
    _onSummarizeComplete(): void;
    muteMicrophone(muted: boolean): void;
    destroy(): Promise<void>;
}
export {};
//# sourceMappingURL=DigitalHumanFrame.d.ts.map