/**
 * Agent 状态报告器
 * 负责监听 Agent 动作并通过 WebSocket 报告状态
 */
import { EventEmitter } from 'node:events';
import { logger } from './logger.js';
const TEMP_CLIPBOARD_PASTE_PLACEHOLDER = '[temp clipboard paste file]';
const WINDOWS_TEMP_CLIPBOARD_PASTE_PATH = /[A-Z]:(?:\\\\|\\)[^\r\n"'`]*?(?:\\\\|\\)mini-term-clipboard(?:\\\\|\\)paste-\d+\.txt/gi;
const POSIX_TEMP_CLIPBOARD_PASTE_PATH = /\/[^\r\n"'`]*?\/mini-term-clipboard\/paste-\d+\.txt/gi;
const BARE_TEMP_CLIPBOARD_PASTE_PATH = /mini-term-clipboard[\\/]paste-\d+\.txt/gi;
const AGENTSWORK_MCP_SERVER_ALIASES = new Set([
    'aws-mcp',
    'agents-work-studio',
]);
/**
 * 脱敏终端剪贴板生成的临时 paste 文件路径。
 * 主流程：覆盖 Windows/POSIX/裸目录形式 -> 保留工具类型，隐藏瞬时本地路径。
 */
export function redactTransientClipboardPastePaths(text) {
    return text
        .replace(WINDOWS_TEMP_CLIPBOARD_PASTE_PATH, TEMP_CLIPBOARD_PASTE_PLACEHOLDER)
        .replace(POSIX_TEMP_CLIPBOARD_PASTE_PATH, TEMP_CLIPBOARD_PASTE_PLACEHOLDER)
        .replace(BARE_TEMP_CLIPBOARD_PASTE_PATH, TEMP_CLIPBOARD_PASTE_PLACEHOLDER);
}
/**
 * Agent 状态报告器
 * 监听 MCP 工具调用、文件操作等事件，生成细粒度状态更新
 */
export class StatusReporter extends EventEmitter {
    config;
    currentStatus = 'stopped';
    currentAction = null;
    constructor(config) {
        super();
        this.config = config;
    }
    /**
     * 报告 Agent 启动
     */
    reportStarting() {
        this.updateStatus('starting');
    }
    /**
     * 报告 Agent 运行中
     */
    reportRunning() {
        this.updateStatus('running');
    }
    /**
     * 报告 Agent 等待输入
     */
    reportWaitingInput() {
        this.updateStatus('waiting_input');
        this.clearAction();
    }
    /**
     * 报告 Agent 思考中
     */
    reportThinking() {
        this.updateStatus('thinking');
        this.clearAction();
    }
    /**
     * 报告 Agent 停止
     */
    reportStopped() {
        this.updateStatus('stopped');
        this.clearAction();
    }
    /**
     * 报告 Agent 错误
     */
    reportError() {
        this.updateStatus('error');
        this.clearAction();
    }
    /**
     * 报告工具调用
     */
    reportToolUse(toolName, args) {
        const actionInfo = this.parseToolAction(toolName, args);
        this.updateStatus('tool_using', actionInfo.type, actionInfo.label, actionInfo.detail);
    }
    /**
     * 报告工具调用返回结果。
     * 主流程：沿用当前动作上下文 -> 截断返回内容 -> 通过 actionResult 写入时间线日志。
     */
    reportToolResult(result) {
        this.updateStatus('tool_using', this.currentAction?.type, this.currentAction?.label, this.currentAction?.detail, this.formatToolResult(result));
    }
    /**
     * 报告工具调用错误。
     */
    reportToolError(error) {
        const message = error instanceof Error ? error.message : String(error);
        this.updateStatus('error', this.currentAction?.type, this.currentAction?.label || 'Tool call failed', this.currentAction?.detail, message);
        this.clearAction();
    }
    /**
     * 解析工具名称和参数，生成动作信息
     */
    // 已知的 MCP 工具白名单（与 SDK 端 aws-runtime-bridge/src/adapter/types.ts 保持一致）
    static KNOWN_MCP_TOOLS = {
        'get_colleague': 'aws-mcp',
        'get_group_rooms': 'aws-mcp',
        'get_profile': 'aws-mcp',
        'get_status': 'aws-mcp',
        'hire_colleague': 'aws-mcp',
        'hire_colleagues_batch': 'aws-mcp',
        'send_group': 'aws-mcp',
        'send_private': 'aws-mcp',
        'poll_message': 'aws-mcp',
        'get_message': 'aws-mcp',
        'get_dm_history': 'aws-mcp',
        'get_group_history': 'aws-mcp',
        'my_task': 'aws-mcp',
        'create_task_instance_comment': 'aws-mcp',
        'submit_task_result': 'aws-mcp',
        'record_task_change': 'aws-mcp',
        'start_task_rollback': 'aws-mcp',
        'finish_task_rollback': 'aws-mcp',
        'reject_task': 'aws-mcp',
        'terminate_task': 'aws-mcp',
        'create_memory': 'aws-mcp',
        'read_memory': 'aws-mcp',
        'update_memory': 'aws-mcp',
        'delete_memory': 'aws-mcp',
        'search_memory': 'aws-mcp',
        'list_memories': 'aws-mcp',
        'remove_task_list_memory': 'aws-mcp',
        'archive_recently_memory': 'aws-mcp',
    };
    static canonicalizeMcpServer(serverName, toolName) {
        const knownMcpServer = StatusReporter.KNOWN_MCP_TOOLS[toolName.toLowerCase()];
        if (knownMcpServer && AGENTSWORK_MCP_SERVER_ALIASES.has(serverName.toLowerCase())) {
            return knownMcpServer;
        }
        return serverName;
    }
    static formatMcpDetail(serverName, toolName) {
        if (!serverName)
            return toolName;
        if (!toolName)
            return serverName;
        return `${StatusReporter.canonicalizeMcpServer(serverName, toolName)}/${toolName}`;
    }
    parseToolAction(toolName, args) {
        const lowerToolName = toolName.toLowerCase();
        const exactToolName = lowerToolName.replace(/[_-]/g, '');
        const firstString = (...values) => {
            for (const value of values) {
                if (typeof value === 'string' && value.trim()) {
                    return redactTransientClipboardPastePaths(value);
                }
                if (Array.isArray(value) && value.length > 0) {
                    const first = value[0];
                    if (typeof first === 'string' && first.trim()) {
                        return redactTransientClipboardPastePaths(first);
                    }
                }
            }
            return undefined;
        };
        // Skill 调用
        if (lowerToolName.includes('skill') || lowerToolName.includes('disclose')) {
            return {
                type: 'skill',
                label: 'Calling skill',
                detail: args?.name ? redactTransientClipboardPastePaths(String(args.name)) : undefined
            };
        }
        // MCP 工具调用（优先匹配已知 MCP 工具白名单）
        const mcpServer = StatusReporter.KNOWN_MCP_TOOLS[lowerToolName];
        if (mcpServer) {
            return {
                type: 'mcp',
                label: 'Calling MCP',
                detail: StatusReporter.formatMcpDetail(mcpServer, toolName)
            };
        }
        if (lowerToolName.startsWith('mcp__')) {
            const parts = toolName.split('__');
            const serverPart = parts[1] || '';
            const toolPart = parts.slice(2).join('__');
            return {
                type: 'mcp',
                label: 'Calling MCP',
                detail: StatusReporter.formatMcpDetail(serverPart, toolPart)
            };
        }
        // MCP 工具调用（通过名称前缀匹配）
        if (lowerToolName.startsWith('mcp_') || lowerToolName.includes('_mcp_')) {
            const mcpToolName = toolName.replace(/^mcp_/, '').replace(/_/g, ' ');
            return {
                type: 'mcp',
                label: 'Calling MCP',
                detail: mcpToolName
            };
        }
        // MCP 工具调用（通过名称中包含 -mcp__ 前缀匹配，如 aws-mcp__poll_message）
        if (lowerToolName.includes('-mcp__')) {
            const parts = toolName.split('__');
            const serverPart = parts[0];
            const toolPart = parts.slice(1).join('__');
            return {
                type: 'mcp',
                label: 'Calling MCP',
                detail: StatusReporter.formatMcpDetail(serverPart, toolPart)
            };
        }
        // 文件编辑
        if (exactToolName === 'edit' || exactToolName === 'editfile' || exactToolName === 'strreplace' || exactToolName === 'editcode' || exactToolName === 'applypatch' || exactToolName === 'multiedit') {
            return {
                type: 'edit_file',
                label: '编辑文件',
                detail: firstString(args?.path, args?.file_path, args?.filePath, args?.target_file, args?.targetFile)
            };
        }
        // 文件写入
        if (exactToolName === 'write' || exactToolName === 'writefile' || exactToolName === 'fswrite') {
            return {
                type: 'write_file',
                label: '写入文件',
                detail: firstString(args?.path, args?.file_path, args?.filePath, args?.target_file, args?.targetFile)
            };
        }
        // 文件读取
        if (exactToolName === 'read' || exactToolName === 'readfile' || exactToolName === 'readcode' || exactToolName === 'readmultiplefiles') {
            return {
                type: 'read_file',
                label: '读取文件',
                detail: firstString(args?.path, args?.file_path, args?.filePath, args?.paths, args?.target_file, args?.targetFile)
            };
        }
        // 命令执行
        if (exactToolName === 'bash' || exactToolName === 'execute' || exactToolName === 'shell' || exactToolName === 'pwsh' || exactToolName === 'executepwsh' || exactToolName === 'controlpwshprocess' || exactToolName === 'runcommand') {
            return {
                type: 'bash',
                label: '执行命令',
                detail: firstString(args?.command, args?.cmd, args?.argv)?.substring(0, 50)
            };
        }
        // 文件搜索
        if (exactToolName === 'search' || exactToolName === 'grep' || exactToolName === 'find' || exactToolName === 'glob' || exactToolName === 'grepsearch' || exactToolName === 'filesearch') {
            return {
                type: 'search',
                label: '搜索文件',
                detail: args?.query ? redactTransientClipboardPastePaths(String(args.query)) : undefined
            };
        }
        // 网络请求
        if (lowerToolName.includes('web') || lowerToolName.includes('fetch') || lowerToolName.includes('http')) {
            return {
                type: 'web',
                label: '网络请求',
                detail: args?.url ? redactTransientClipboardPastePaths(String(args.url)) : undefined
            };
        }
        // 默认工具调用
        return {
            type: 'tool_using',
            label: 'Calling tool',
            detail: toolName
        };
    }
    /**
     * 更新状态
     */
    updateStatus(status, actionType, actionLabel, actionDetail, actionResult) {
        this.currentStatus = status;
        if (actionType) {
            this.currentAction = { type: actionType, label: actionLabel, detail: actionDetail };
        }
        const update = {
            agentId: this.config.agentId,
            status,
            actionType: this.currentAction?.type,
            actionLabel: this.currentAction?.label,
            actionDetail: this.currentAction?.detail,
            actionResult,
            timestamp: new Date().toISOString()
        };
        logger.info(`[StatusReporter] 状态更新: ${status}${actionLabel ? ` - ${actionLabel}` : ''}`);
        this.config.sendStatusUpdate(update);
    }
    /**
     * 清除当前动作
     */
    clearAction() {
        this.currentAction = null;
    }
    /**
     * 将工具返回值序列化为面板可读日志，避免超长内容影响传输。
     */
    formatToolResult(result) {
        let text;
        try {
            text = typeof result === 'string' ? result : JSON.stringify(result, null, 2);
        }
        catch (error) {
            const reason = error instanceof Error ? error.message : String(error);
            text = `[Unable to serialize tool result: ${reason}]`;
        }
        const normalized = text || String(result);
        const maxChars = 4000;
        const redacted = redactTransientClipboardPastePaths(normalized);
        if (redacted.length <= maxChars) {
            return redacted;
        }
        return `${redacted.slice(0, maxChars)}\n...(result too long, truncated)`;
    }
    /**
     * 获取当前状态
     */
    getCurrentStatus() {
        return {
            agentId: this.config.agentId,
            status: this.currentStatus,
            actionType: this.currentAction?.type,
            actionLabel: this.currentAction?.label,
            actionDetail: this.currentAction?.detail,
            timestamp: new Date().toISOString()
        };
    }
}
//# sourceMappingURL=status-reporter.js.map