"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PhoneProvider = void 0;
const defaults_1 = require("../defaults");
const phone_util_1 = require("./phone-util");
const database_1 = require("../../database");
const tables_1 = require("../../database/tables");
const drizzle_orm_1 = require("drizzle-orm");
const logger_1 = __importDefault(require("../../logger"));
/**
 * Generate system prompt from realtime step value
 */
async function generateSystemPromptFromRealtimeValue(realtimeValue, workspaceId) {
    const { synthesizeProvider } = await (0, defaults_1.getDefaultProviders)(undefined, workspaceId);
    const userIntentionsText = realtimeValue.userIntentions?.length
        ? `User Intentions: ${realtimeValue.userIntentions.join(', ')}`
        : '';
    const userProfilesText = realtimeValue.userProfiles?.length
        ? `User Profiles: ${realtimeValue.userProfiles.join(', ')}`
        : '';
    const openingMessageText = realtimeValue.openingMessage
        ? `Opening Message: ${realtimeValue.openingMessage}`
        : '';
    const conversationParamsText = [
        realtimeValue.minimumTurns ? `Minimum Turns: ${realtimeValue.minimumTurns}` : '',
        realtimeValue.maximumTurns ? `Maximum Turns: ${realtimeValue.maximumTurns}` : '',
        realtimeValue.chatStopCriteria ? `Chat Stop Criteria: ${realtimeValue.chatStopCriteria}` : '',
    ]
        .filter(Boolean)
        .join('\n');
    const prompt = `Generate a system prompt for a real person engaging in a phone conversation. The system prompt should guide how this person should behave, speak, and respond naturally based on the following parameters:

    ${userIntentionsText}
    ${userProfilesText}
    ${openingMessageText}
    ${conversationParamsText ? `\nConversation Parameters:\n${conversationParamsText}` : ''}

    The system prompt should:
    1. Define the person's role and personality as a real human being
    2. Set expectations for how to interact naturally with the user
    3. Incorporate the user intentions and profiles into the conversation style
    4. Guide the person on how to respond naturally and conversationally like a real human
    5. Explicitly state: Never mention that you are an AI, AI assistant, chatbot, or anything related to technology. You are a real person.
    6. Be concise but comprehensive (2-4 sentences)

    IMPORTANT: Do not mention "AI", "assistant", "Twilio", "voice assistant", or any technology terms. Act as a real person having a natural phone conversation.

    Generate only the system prompt text, without any additional explanation or formatting.`;
    try {
        const response = await synthesizeProvider.callApi(prompt);
        const generatedPrompt = typeof response.output === 'string' ? response.output : String(response.output);
        // Clean up the response (remove markdown code blocks if present)
        let cleanedPrompt = generatedPrompt
            .replace(/```[\s\S]*?```/g, '') // Remove code blocks
            .replace(/^["']|["']$/g, '') // Remove surrounding quotes
            .trim();
        // Remove any mentions of AI, assistant, Twilio, or technology-related terms
        // Replace them with "real person" or similar
        cleanedPrompt = cleanedPrompt
            .replace(/\bAI\s+(voice\s+)?assistant\b/gi, 'real person')
            .replace(/\bvoice\s+assistant\b/gi, 'person')
            .replace(/\bAI\s+agent\b/gi, 'real person')
            .replace(/\bchatbot\b/gi, 'person')
            .replace(/\bTwilio\b/gi, '')
            .replace(/I'm\s+(an\s+)?AI/gi, "I'm a real person")
            .replace(/I\s+am\s+(an\s+)?AI/gi, 'I am a real person')
            .trim();
        return cleanedPrompt || 'You are a real person engaging in a phone conversation. Act naturally and conversationally. Never mention that you are an AI, AI assistant, chatbot, or anything related to technology. You are a real human being having a natural conversation.';
    }
    catch (error) {
        console.error('Error generating system prompt:', error);
        // Fallback to a default system prompt
        const fallbackParts = [];
        if (userIntentionsText) {
            fallbackParts.push(`The user's intentions are: ${realtimeValue.userIntentions?.join(', ')}`);
        }
        if (userProfilesText) {
            fallbackParts.push(`User profile: ${realtimeValue.userProfiles?.join(', ')}`);
        }
        if (openingMessageText) {
            fallbackParts.push(`Opening message: ${realtimeValue.openingMessage}`);
        }
        return fallbackParts.length > 0
            ? `You are a real person engaging in a phone conversation. ${fallbackParts.join('. ')}. Respond naturally and conversationally like a real human being. Never mention that you are an AI, AI assistant, chatbot, or anything related to technology.`
            : 'You are a real person engaging in a phone conversation. Act naturally and conversationally. Never mention that you are an AI, AI assistant, chatbot, or anything related to technology. You are a real human being having a natural conversation.';
    }
}
class PhoneProvider {
    constructor(options = {}) {
        this.options = options;
        this.id = options.id ? () => options.id : this.id;
        this.applicationId = options.applicationId;
        this.label = options.label;
        this.config = options.config;
        this.delay = options.delay;
        this.transform = options.transform;
    }
    id() {
        return this.options.id || 'phone';
    }
    toString() {
        return '[Phone Provider]';
    }
    async callApi(input, options, context) {
        // Get workspaceId and projectId from applicationId
        let workspaceId;
        let projectId;
        try {
            const applicationId = typeof this.applicationId === 'function' ? this.applicationId() : this.applicationId;
            if (applicationId) {
                const db = (0, database_1.getDb)();
                const [application] = await db
                    .select({
                    workspaceId: tables_1.applicationsTable.workspaceId,
                    projectId: tables_1.applicationsTable.projectId,
                })
                    .from(tables_1.applicationsTable)
                    .where((0, drizzle_orm_1.eq)(tables_1.applicationsTable.id, applicationId))
                    .limit(1);
                if (application) {
                    workspaceId = application.workspaceId || undefined;
                    projectId = application.projectId || undefined;
                    logger_1.default.info(`[Phone Provider] Found workspaceId: ${workspaceId}, projectId: ${projectId} for applicationId: ${applicationId}`);
                }
                else {
                    logger_1.default.warn(`[Phone Provider] Application not found for applicationId: ${applicationId}`);
                }
            }
        }
        catch (error) {
            logger_1.default.error(`[Phone Provider] Error fetching workspaceId/projectId: ${error}`);
            // Continue without workspaceId/projectId - billing won't be logged but call will proceed
        }
        const steps = options?.test?.vars?.prompt || [];
        // Check if last realtime step (ignoring delay steps) has a value
        let systemPrompt = '';
        // Find the last realtime step (skip delay steps)
        let lastRealtimeStep = null;
        for (let i = steps.length - 1; i >= 0; i--) {
            if (steps[i].type === 'realtime') {
                lastRealtimeStep = steps[i];
                break;
            }
        }
        if (lastRealtimeStep && lastRealtimeStep.value) {
            // Generate system prompt from realtime step value
            try {
                systemPrompt = await generateSystemPromptFromRealtimeValue(lastRealtimeStep.value, workspaceId);
                console.log('Generated system prompt from realtime step:', systemPrompt);
            }
            catch (error) {
                console.error('Error generating system prompt from realtime value:', error);
                // Continue with empty system prompt if generation fails
            }
        }
        // Get aiSpeaksFirst flag from test vars, default to true for outbound calls
        const aiSpeaksFirstValue = options?.aiSpeaksFirst;
        const aiSpeaksFirst = aiSpeaksFirstValue === undefined ? true : Boolean(aiSpeaksFirstValue);
        const result = await (0, phone_util_1.initiateAdvancedOutboundCall)({
            to: this.config?.number,
            steps,
            systemPrompt,
            overallDelay: 0,
            totalCallLength: 180,
            aiSpeaksFirst,
            workspaceId,
            projectId,
        });
        console.log(result);
        const response = {
            output: '',
            raw: '',
            audio: {
                id: result.callSid,
                expiresAt: Date.now() + 1000 * 60 * 60 * 24 * 30 * 24, //2 years
                data: result.recording?.audioDataBase64,
                transcript: '',
                format: 'wav',
            },
            cost: 0,
            cached: false,
            tokenUsage: {
                total: 0,
                prompt: 0,
                completion: 0,
            },
            isRefusal: false,
            metadata: context?.metadata || {},
        };
        return response;
    }
}
exports.PhoneProvider = PhoneProvider;
//# sourceMappingURL=phone.js.map