/**
 * AgentRouter.ts — 跨 iframe Agent 注册、发现与任务转发路由器
 *
 * 每个 KeepworkSDK 实例（在任意 window / iframe 中）持有一个 AgentRouter。
 * 命名 ChatSession 可向本地路由器注册；路由器通过 `window.postMessage`
 * 在整个 iframe 树中广播可用性，使任何 `submitTask` 调用都能发现并委托远程 agent。
 *
 * ## 协议约定
 * - 所有 AgentRouter 消息携带 `is_agent_router: true` 标志
 * - NPL 模块使用 `is_paracraft_message: true`，两者互不干扰
 * - 同一消息的 `instanceId` / `sourceInstanceId` 等于本路由器 ID 时视为自回显，丢弃
 *
 * ## 使用示例
 * ```ts
 * // 在拥有 agent 的 iframe 中
 * const router = window.keepwork.agentRouter;
 * router.register('codeHelper', session);
 *
 * // 在父页面或其他 iframe 中
 * const router = window.keepwork.agentRouter;
 * router.addChildWindow(iframe.contentWindow);
 * const result = await router.submitTask('codeHelper', { task: 'Explain KeepworkSDK' });
 * ```
 */
/** AgentRouter 协议消息类型字符串 */
declare const MSG: {
    readonly REGISTER: "agent_register";
    readonly REGISTER_ACK: "agent_register_ack";
    readonly REGISTER_REJECT: "agent_register_reject";
    readonly UNREGISTER: "agent_unregister";
    readonly WINDOW_DISCONNECT: "agent_window_disconnect";
    readonly TASK: "agent_task";
    readonly TASK_RESULT: "agent_task_result";
    readonly STREAM: "agent_stream";
    readonly SYNC_ACK: "agent_sync_ack";
};
type MsgType = typeof MSG[keyof typeof MSG];
/** AgentRouter 协议消息信封 */
interface RouterMessage {
    is_agent_router: true;
    type: MsgType;
    agentName?: string;
    instanceId?: string;
    sourceInstanceId?: string;
    taskId?: string;
    payload?: TaskPayload;
    result?: unknown;
    error?: string | null;
    reason?: string;
    syncId?: string;
    request?: boolean;
    syncBackfill?: boolean;
    streamType?: string;
    content?: unknown;
    fullResponse?: unknown;
    isRestartAgentSignal?: boolean;
    promptFile?: string;
    tools?: unknown[];
    options?: Record<string, unknown>;
}
/** 任务载荷（submitTask 时传入） */
export interface TaskPayload {
    task?: string;
    description?: string;
    /** LLM 工具列表（传给 session.send） */
    tools?: unknown;
    maxIterations?: number;
    systemPrompt?: string;
    model?: string;
    thinking?: unknown;
    callbackMode?: string;
    debounceSeconds?: number;
    /** 是否绕过 LLM 直接执行工具 */
    toolCallOnly?: boolean;
    fnName?: string;
    fnArgs?: unknown;
    [key: string]: unknown;
}
/** 路由表条目 */
interface RouteRecord {
    windowRef: WindowProxy | NPLWindowProxy;
    sourceInstanceId: string;
    learnedFrom: WindowProxy | NPLWindowProxy;
    updatedAt: number;
}
/** 任务注册表条目 */
interface OriginTaskRecord {
    kind: 'origin';
    agentName: string;
    createdAt: number;
    outboundWindow: WindowProxy | NPLWindowProxy;
    replyWindow: null;
    onStream: ((msg: RouterMessage) => void) | null;
    resolve: (value: unknown) => void;
    reject: (reason: unknown) => void;
    timeoutId: ReturnType<typeof setTimeout> | null;
}
interface RelayTaskRecord {
    kind: 'relay';
    agentName: string;
    createdAt: number;
    outboundWindow: WindowProxy | NPLWindowProxy;
    replyWindow: WindowProxy | NPLWindowProxy;
    onStream: null;
    resolve: null;
    reject: null;
    timeoutId: null;
}
type TaskRecord = OriginTaskRecord | RelayTaskRecord;
/** 本地 agent session 接口（ChatSession 的最小接口） */
interface AgentSession {
    handleTask?: (taskId: string, payload: TaskPayload, streamCb: (event: unknown) => void) => Promise<unknown>;
    executeTool?: (fnName: string, fnArgs: unknown) => Promise<unknown>;
    clear?: () => void;
    send?: (task: string, options: Record<string, unknown>) => Promise<unknown>;
    messages?: unknown[];
    options?: Record<string, unknown>;
}
/** submitTask 的回调选项 */
export interface SubmitTaskCallbacks {
    onStream?: (msg: RouterMessage) => void;
}
/**
 * NPLWindowProxy — 通过 NPLJS 向 Lua 端转发 postMessage 的虚拟 WindowProxy。
 *
 * 从 AgentRouter 的视角，此对象与真实 WindowProxy 完全等价：
 * 同样存储在 `connectedWindows` 和 `routeTable` 中。
 * `_sendTo()` 通过检测 `_isNPLWindowProxy` 标志选择 NPLJS 通道而非 postMessage。
 */
declare class NPLWindowProxy {
    readonly _isNPLWindowProxy = true;
    private _npljs;
    private _sendEventName;
    /**
     * @param npljs         - NPLJS 实例（需暴露 SendMsg / OnMsg）
     * @param sendEventName - JS→Lua 方向的 NPLJS 事件名
     */
    constructor(npljs: {
        SendMsg: (event: string, msg: unknown) => void;
    }, sendEventName: string);
    /**
     * 模拟 window.postMessage，通过 NPLJS 发送消息到 Lua 端。
     * @param msg - 要发送的消息对象
     */
    postMessage(msg: unknown): void;
}
declare class AgentRouter {
    /** 开启详细日志（调试用）。 */
    static debug: boolean;
    static _log(msgOrFn: string | (() => string), ...rest: unknown[]): void;
    /** 此路由器实例的唯一 ID。 */
    readonly instanceId: string;
    /** 本地注册的 agent（agentName → session）。 */
    readonly localAgents: Map<string, {
        session: AgentSession;
    }>;
    /**
     * 远程 agent 路由表（agentName → RouteRecord）。
     * 记录消息应该发往哪个 windowRef 才能抵达对应 agent。
     */
    readonly routeTable: Map<string, RouteRecord>;
    /**
     * 任务注册表（taskId → TaskRecord）。
     * origin 任务：由本路由器提交，持有 resolve/reject 回调。
     * relay 任务：上游转发过来，需要将结果/流转发回 replyWindow。
     */
    readonly taskRegistry: Map<string, TaskRecord>;
    /** window → 从该 window 学到的 agent 名集合（O(1) 清理索引）。 */
    readonly windowAgents: Map<Window | NPLWindowProxy, Set<string>>;
    /** window → 通过该 window 流转的 taskId 集合（O(1) 清理索引）。 */
    readonly windowTasks: Map<Window | NPLWindowProxy, Set<string>>;
    /** 已连接的子 iframe window 集合。 */
    readonly connectedWindows: Set<Window | NPLWindowProxy>;
    private _isDestroyed;
    private _disconnectAnnounced;
    private _messageHandler;
    private _lifecycleHandler;
    private _pendingSyncs;
    private _nplWindowProxy;
    private _nplRecvEventName;
    /** 关联的 SDK 实例（用于读取 timeout 配置）。 */
    _sdk?: {
        timeout?: number;
    };
    constructor();
    /**
     * 在本路由器注册命名 agent，并向 iframe 树广播可用性。
     * 若名称已被占用（本地或远程），返回 false。
     *
     * @param agentName - agent 唯一名称
     * @param session   - 处理该 agent 任务的 ChatSession 实例
     * @returns 注册成功返回 true，名称冲突返回 false
     */
    register(agentName: string, session: AgentSession): boolean;
    /**
     * 注销本地 agent 并广播移除消息。
     * @param agentName - 要注销的 agent 名称
     */
    unregister(agentName: string): void;
    /**
     * 检查 agent（本地或远程）是否已知。
     * @param agentName - agent 名称
     */
    hasAgent(agentName: string): boolean;
    /**
     * 检查 agent 是否只存在于路由表（即在另一个 iframe 中）。
     * @param agentName - agent 名称
     */
    hasRemoteAgent(agentName: string): boolean;
    /**
     * 等待 agent 出现（轮询路由表 / 注册事件），若已存在则立即 resolve。
     *
     * @param agentName - agent 名称
     * @param timeout   - 最大等待毫秒数（默认 5000）
     */
    waitForAgent(agentName: string, timeout?: number): Promise<void>;
    /**
     * 向远程 agent 提交任务，返回 Promise 等待结果。
     *
     * @param agentName - 目标 agent 名称
     * @param payload   - 任务载荷（task / tools / maxIterations / systemPrompt / model 等）
     * @param callbacks - 可选：onStream 流式回调
     * @returns agent 任务结果
     */
    submitTask(agentName: string, payload: TaskPayload, callbacks?: SubmitTaskCallbacks): Promise<unknown>;
    /**
     * 注册子 iframe 的 contentWindow 以加入路由树。
     * 自动发起同步重试，直到子窗口确认。
     *
     * @param windowRef - 子 iframe 的 contentWindow（或 NPLWindowProxy）
     */
    addChildWindow(windowRef: WindowProxy | NPLWindowProxy): void;
    /**
     * 移除子 iframe window，清理其相关路由和任务。
     * @param windowRef - 要移除的 window
     */
    removeChildWindow(windowRef: WindowProxy | NPLWindowProxy): void;
    /**
     * 销毁路由器：广播断开通知、注销所有 agent、拒绝所有待处理任务、清理监听器。
     * 调用后此实例不可再使用。
     */
    destroy(): void;
    /**
     * 将本路由器与 Lua 侧 AgentRouter.lua 通过 NPLJS 连接。
     *
     * 创建 NPLWindowProxy 并将其插入现有路由基础设施，
     * AgentRouter 协议消息通过 NPLJS 透明转发，而非 postMessage。
     *
     * @param npljs   - NPLJS 实例（需提供 SendMsg / OnMsg）
     * @param options - sendEventName（JS→Lua）/ recvEventName（Lua→JS）
     * @returns this（链式调用）
     */
    attachNPLJS(npljs: {
        SendMsg: (event: string, msg: unknown) => void;
        OnMsg: (event: string, cb: (data: unknown) => void) => void;
        OffMsg: (event: string) => void;
    }, options?: {
        sendEventName?: string;
        recvEventName?: string;
    }): this;
    /**
     * 断开通过 attachNPLJS 建立的 NPLJS 桥接。
     *
     * @param npljs - 与 attachNPLJS 相同的 NPLJS 实例
     */
    detachNPLJS(npljs: {
        OffMsg: (event: string) => void;
    }): void;
    /**
     * 向指定 window 发送消息。
     * NPLWindowProxy 通过 NPLJS 路由，普通 WindowProxy 通过 postMessage。
     * @private
     */
    private _sendTo;
    /**
     * 广播消息到父窗口和所有子 iframe，排除指定 window（防止回显循环）。
     * @private
     */
    private _broadcast;
    /** @private 主消息事件处理器。 */
    private _onMessage;
    /** @private 处理 agent_register 消息：存储路由并转发。 */
    private _handleRegister;
    /** @private 处理 agent_register_ack（当前仅记录日志）。 */
    private _handleRegisterAck;
    /** @private 处理 agent_register_reject（回滚本地乐观注册）。 */
    private _handleRegisterReject;
    /** @private 处理 agent_unregister（验证来源后删除路由，防止劫持）。 */
    private _handleUnregister;
    /** @private 处理 agent_window_disconnect：清理该 window 的所有路由和任务。 */
    private _handleWindowDisconnect;
    /** @private 处理 agent_task：本地执行或转发到正确的 window。 */
    private _handleTask;
    /** @private 在本地 session 上执行任务（handleTask 接口 或 legacy send 接口）。 */
    private _executeLocalTask;
    /**
     * @private 直接执行工具调用（bypasses LLM，payload.toolCallOnly=true 时调用）。
     * 支持 RestartAgentSignal 跨 iframe 序列化。
     */
    private _executeLocalToolCall;
    /** @private 处理 agent_task_result：resolve origin 任务或向上游中继。 */
    private _handleTaskResult;
    /** @private 处理 agent_stream：转发给 origin 回调或向上游中继。 */
    private _handleStream;
    /** @private 处理 agent_sync_ack：响应或确认同步。 */
    private _handleSyncAck;
    /** @private 创建 origin 任务记录（带超时自动拒绝）。 */
    private _createOriginTask;
    /** @private 创建 relay 任务记录（转发上游任务）。 */
    private _createRelayTask;
    /**
     * @private 幂等移除任务：清理超时、删除 window 索引，返回被删除的记录（已删除返回 null）。
     */
    private _clearTask;
    private _indexWindowAgent;
    private _indexWindowTask;
    private _isExpectedTaskSource;
    /**
     * @private 断开 window 时的确定性清理：
     * 1. 从 connectedWindows 删除
     * 2. 删除该 window 持有的所有路由，广播 UNREGISTER
     * 3. 失败该 window 关联的所有任务（origin reject / relay 通知上游）
     */
    private _cleanupWindow;
    /**
     * @private 将已知的所有 agent（本地 + 路由表）同步到指定 window。
     * backfill 消息携带 syncBackfill:true，防止接收方递归回传。
     */
    private _syncKnownAgentsToWindow;
    /**
     * @private 带重试的 agent 同步（Phase 1 快速重试 ~5s，Phase 2 每 5s 一次）。
     * 子窗口确认后停止。
     */
    private _syncWithRetry;
    /** @private 广播 window_disconnect 通知（幂等）。 */
    private _announceWindowDisconnect;
    /** @private 页面生命周期钩子：pagehide 时销毁（bfcache 保留的页面除外）。 */
    private _handleLifecycleTeardown;
}
export default AgentRouter;
export { NPLWindowProxy };
//# sourceMappingURL=AgentRouter.d.ts.map