/**
 * src/tools/executor-wrapper.ts
 * Tool Executor Wrapper — Adds approval workflow to tool execution
 */
import { createChildLogger } from '../utils/logger.js';
import { getToolByName } from './types.js';
import { requestApproval, requiresApproval, getRiskLevel, decideApproval, getApprovalRequest } from '../approval/manager.js';
const log = createChildLogger('tools:executor-wrapper');
/**
 * Execute a tool with approval check
 */
export async function executeToolWithApproval(options) {
    const { tenantId, sessionId, toolName, args, waitForApproval = true } = options;
    // Check if tool requires approval
    if (!requiresApproval(toolName)) {
        // Safe tool, execute directly
        return executeTool(toolName, args);
    }
    // Request approval
    const riskLevel = getRiskLevel(toolName, args);
    const reason = `Agent wants to execute ${toolName} with args: ${JSON.stringify(args)}`;
    const approvalRequest = await requestApproval(tenantId, sessionId, toolName, args, reason, riskLevel);
    log.info({ requestId: approvalRequest.id, toolName, riskLevel }, 'Waiting for approval');
    if (!waitForApproval) {
        return {
            success: false,
            output: `Approval required but not waiting. Request ID: ${approvalRequest.id}`,
            durationMs: 0,
        };
    }
    // Wait for approval (polling)
    const startTime = Date.now();
    const timeout = options.approvalTimeoutMs || 900000; // 15 minutes default
    while (Date.now() - startTime < timeout) {
        const req = await getApprovalRequest(approvalRequest.id);
        if (!req) {
            return {
                success: false,
                output: 'Approval request not found',
                durationMs: Date.now() - startTime,
            };
        }
        if (req.status === 'approved') {
            log.info({ requestId: req.id }, 'Approval granted, executing tool');
            return executeTool(toolName, args);
        }
        if (req.status === 'denied') {
            log.info({ requestId: req.id }, 'Approval denied');
            return {
                success: false,
                output: 'Tool execution denied by user',
                durationMs: Date.now() - startTime,
            };
        }
        // Still pending, wait a bit
        await new Promise(resolve => setTimeout(resolve, 5000));
    }
    return {
        success: false,
        output: 'Approval timeout',
        durationMs: Date.now() - startTime,
    };
}
/**
 * Execute a tool directly (no approval check)
 */
async function executeTool(toolName, args) {
    const tool = getToolByName(toolName);
    if (!tool) {
        return {
            success: false,
            output: `Tool not found: ${toolName}`,
            durationMs: 0,
        };
    }
    try {
        // Assuming tool has an execute method
        const result = await tool.execute(args);
        return {
            ...result,
            durationMs: result.durationMs || 0,
        };
    }
    catch (err) {
        const error = err instanceof Error ? err.message : String(err);
        log.error({ toolName, error }, 'Tool execution failed');
        return {
            success: false,
            output: error,
            durationMs: 0,
        };
    }
}
/**
 * Handle approval decision from user message
 * Call this when a user replies to an approval request
 */
export async function handleApprovalResponse(requestId, userMessage, approvedBy) {
    const req = await getApprovalRequest(requestId);
    if (!req) {
        return { success: false, message: 'Approval request not found' };
    }
    if (req.status !== 'pending') {
        return { success: false, message: `Request already decided: ${req.status}` };
    }
    const decision = {
        approved: userMessage.includes('✅') || userMessage.toLowerCase().includes('approve') || userMessage.toLowerCase().includes('yes'),
        reason: userMessage,
    };
    if (!decision.approved && !userMessage.toLowerCase().includes('deny') && !userMessage.toLowerCase().includes('no')) {
        // Ambiguous response
        return { success: false, message: 'Please reply with ✅ to approve or ❌ to deny' };
    }
    await decideApproval(requestId, decision, approvedBy);
    return {
        success: true,
        message: decision.approved ? 'Approval granted' : 'Approval denied',
    };
}
//# sourceMappingURL=executor-wrapper.js.map