  1555→                    'Write a follow-up email',
  1556→                    'Compose a polite decline',
  1557→                    'Draft a meeting request'
  1558→                ]
  1559→            }
  1560→        };
  1561→
  1562→        let selectedAgent = 'general';
  1563→
  1564→        // ============================================
  1565→        // DEEP ANALYSIS — Automated 5-Pass
  1566→        // ============================================
  1567→        const DEEP_ANALYSIS_PASSES = [
  1568→            {
  1569→                id: 'timeline',
  1570→                name: 'Business Relationship Timeline',
  1571→                agent: 'general',
  1572→                prompt: 'Analyze the COMPLETE email history chronologically. Build a detailed timeline of the business relationship:\n\n1. KEY MILESTONES: When did the relationship start? What were the major projects/deals? When did things start going wrong? When did we lose them?\n2. TURNING POINTS: Identify the exact moments where the relationship shifted negatively. Quote specific emails.\n3. OUR MISTAKES: What did we do wrong? Late deliveries, missed expectations, poor communication, pricing issues? Be brutally honest.\n4. THEIR SATISFACTION CURVE: Rate their satisfaction (1-10) at each major point in the timeline.\n5. UNRESOLVED ISSUES: What was never properly addressed or closed?\n6. LAST INTERACTION: What was the tone and content of our last exchange? Did we leave the door open?'
  1573→            },
  1574→            {
  1575→                id: 'pressure',
  1576→                name: 'Pressure & Manipulation Detection',
  1577→                agent: 'deception_detector',
  1578→                prompt: 'Analyze ALL emails from the other party\'s team members for:\n\n1. PRESSURE TACTICS: Where did they push unreasonable deadlines, scope changes, or price reductions? Quote specific examples.\n2. BROKEN PROMISES from their side: Did they commit to volumes, timelines, payments that didn\'t materialize?\n3. DOUBLE STANDARDS: Did they hold us to standards they didn\'t meet themselves?\n4. ESCALATION PATTERNS: When and why did they escalate to the CEO? Was it justified or a power play?\n5. BLAME SHIFTING: Did they blame us for problems that were partially/fully their responsibility?\n6. GOOD FAITH SIGNALS: To be fair — where were they genuinely reasonable or helpful?\n\nRate each team member\'s negotiation tactics: FAIR / AGGRESSIVE / MANIPULATIVE with evidence.'
  1579→            },
  1580→            {
  1581→                id: 'profiles',
  1582→                name: 'Psychological Profiles',
  1583→                agent: 'contact_profiler',
  1584→                prompt: 'Build detailed psychological and business profiles for EACH person from the other party in these emails. For each person provide:\n\n1. NAME & ROLE (infer from email signatures and context)\n2. COMMUNICATION STYLE: Formal/casual, direct/indirect, emotional/analytical\n3. DECISION-MAKING: Do they decide alone or need approval? Fast or slow? Risk-averse?\n4. WHAT MOTIVATES THEM: Price? Quality? Relationships? Status? Control?\n5. HOW THEY HANDLE CONFLICT: Confrontational, avoidant, diplomatic, passive-aggressive?\n6. THEIR INFLUENCE: Who has real power vs who is just executing?\n7. THEIR ATTITUDE TOWARD US: Positive, neutral, negative? Did it change over time?\n8. APPROACH STRATEGY: How should we approach THIS specific person to rebuild the relationship?\n\nPay special attention to the CEO — what drives them, what frustrates them, what would win them back?'
  1585→            },
  1586→            {
  1587→                id: 'financial',
  1588→                name: 'Financial & Business Patterns',
  1589→                agent: 'quote_analyst',
  1590→                prompt: 'Analyze the complete financial and business history:\n\n1. ALL PRICES QUOTED: Every amount, every project, every change order — create a table\n2. PRICING TRENDS: Did our prices go up/down? Did they push for discounts? How much did we concede?\n3. SCOPE CREEP: Where did work expand beyond original quotes without matching price increases?\n4. PAYMENT BEHAVIOR: Were they prompt payers? Any disputes over invoices?\n5. VOLUME vs COMMITMENT: Did they promise volume that didn\'t materialize?\n6. COMPETITOR MENTIONS: Did they mention other suppliers? Use competitor pricing as leverage?\n7. PROFITABILITY ASSESSMENT: Based on the patterns, were they a profitable client or were we losing money?\n8. RE-ENGAGEMENT PRICING: What pricing strategy should we use to win them back without repeating past mistakes?'
  1591→            },
  1592→            {
  1593→                id: 'winback',
  1594→                name: 'Win-Back Strategy',
  1595→                agent: 'general',
  1596→                prompt: 'Based on everything in these emails AND your previous analysis passes (timeline, pressure tactics, profiles, financials), create a CONCRETE win-back strategy:\n\n1. ROOT CAUSE SUMMARY: In 3 sentences, why did we lose them?\n2. WHAT THEY VALUED: What did they actually appreciate about working with us?\n3. WHAT THEY HATED: What were their consistent pain points?\n4. COMPETITIVE POSITION: What would make them choose us over their current supplier?\n5. APPROACH PLAN:\n   - WHO to contact first (and why that person)\n   - WHEN (timing considerations based on their business cycle)\n   - HOW (email, call, in-person meeting?)\n   - WHAT to say (draft an opening message)\n   - WHAT TO OFFER (specific value proposition addressing their known pain points)\n6. RED LINES: What should we NOT agree to if they come back? What terms caused problems before?\n7. SUCCESS METRICS: How will we know the re-engagement is working?\n\nBe specific. Reference actual names, actual issues, actual quotes from the emails.'
  1597→            }
  1598→        ];
  1599→
  1600→        // ============================================
  1601→        // TOKEN ESTIMATION
  1602→        // ============================================
  1603→        const MODEL_LIMITS = {
  1604→            'claude-opus-4-6': 200000,
  1605→            'claude-sonnet-4-6': 200000,
  1606→            'claude-sonnet-4-5-20250929': 200000,
  1607→            'claude-3-5-sonnet-20241022': 200000,
  1608→            'claude-opus-4-5-20250929': 200000,
  1609→            'claude-3-opus-20240229': 200000,
  1610→            'claude-3-5-haiku-20241022': 200000,
  1611→            'gpt-4o': 128000,
  1612→            'gpt-4o-mini': 128000,
  1613→            'gpt-4-turbo': 128000,
  1614→            'gpt-4.1': 1000000,

                    'Write a follow-up email',
                    'Compose a polite decline',
                    'Draft a meeting request'
                ]
            }
        };

        let selectedAgent = 'general';

        // ============================================
        // DEEP ANALYSIS — Automated 5-Pass
        // ============================================
        const DEEP_ANALYSIS_PASSES = [
            {
                id: 'timeline',
                name: 'Business Relationship Timeline',
                agent: 'general',
                prompt: 'Analyze the COMPLETE email history chronologically. Build a detailed timeline of the business relationship:\n\n1. KEY MILESTONES: When did the relationship start? What were the major projects/deals? When did things start going wrong? When did we lose them?\n2. TURNING POINTS: Identify the exact moments where the relationship shifted negatively. Quote specific emails.\n3. OUR MISTAKES: What did we do wrong? Late deliveries, missed expectations, poor communication, pricing issues? Be brutally honest.\n4. THEIR SATISFACTION CURVE: Rate their satisfaction (1-10) at each major point in the timeline.\n5. UNRESOLVED ISSUES: What was never properly addressed or closed?\n6. LAST INTERACTION: What was the tone and content of our last exchange? Did we leave the door open?'
            },
            {
                id: 'pressure',
                name: 'Pressure & Manipulation Detection',
                agent: 'deception_detector',
                prompt: 'Analyze ALL emails from the other party\'s team members for:\n\n1. PRESSURE TACTICS: Where did they push unreasonable deadlines, scope changes, or price reductions? Quote specific examples.\n2. BROKEN PROMISES from their side: Did they commit to volumes, timelines, payments that didn\'t materialize?\n3. DOUBLE STANDARDS: Did they hold us to standards they didn\'t meet themselves?\n4. ESCALATION PATTERNS: When and why did they escalate to the CEO? Was it justified or a power play?\n5. BLAME SHIFTING: Did they blame us for problems that were partially/fully their responsibility?\n6. GOOD FAITH SIGNALS: To be fair — where were they genuinely reasonable or helpful?\n\nRate each team member\'s negotiation tactics: FAIR / AGGRESSIVE / MANIPULATIVE with evidence.'
            },
            {
                id: 'profiles',
                name: 'Psychological Profiles',
                agent: 'contact_profiler',
                prompt: 'Build detailed psychological and business profiles for EACH person from the other party in these emails. For each person provide:\n\n1. NAME & ROLE (infer from email signatures and context)\n2. COMMUNICATION STYLE: Formal/casual, direct/indirect, emotional/analytical\n3. DECISION-MAKING: Do they decide alone or need approval? Fast or slow? Risk-averse?\n4. WHAT MOTIVATES THEM: Price? Quality? Relationships? Status? Control?\n5. HOW THEY HANDLE CONFLICT: Confrontational, avoidant, diplomatic, passive-aggressive?\n6. THEIR INFLUENCE: Who has real power vs who is just executing?\n7. THEIR ATTITUDE TOWARD US: Positive, neutral, negative? Did it change over time?\n8. APPROACH STRATEGY: How should we approach THIS specific person to rebuild the relationship?\n\nPay special attention to the CEO — what drives them, what frustrates them, what would win them back?'
            },
            {
                id: 'financial',
                name: 'Financial & Business Patterns',
                agent: 'quote_analyst',
                prompt: 'Analyze the complete financial and business history:\n\n1. ALL PRICES QUOTED: Every amount, every project, every change order — create a table\n2. PRICING TRENDS: Did our prices go up/down? Did they push for discounts? How much did we concede?\n3. SCOPE CREEP: Where did work expand beyond original quotes without matching price increases?\n4. PAYMENT BEHAVIOR: Were they prompt payers? Any disputes over invoices?\n5. VOLUME vs COMMITMENT: Did they promise volume that didn\'t materialize?\n6. COMPETITOR MENTIONS: Did they mention other suppliers? Use competitor pricing as leverage?\n7. PROFITABILITY ASSESSMENT: Based on the patterns, were they a profitable client or were we losing money?\n8. RE-ENGAGEMENT PRICING: What pricing strategy should we use to win them back without repeating past mistakes?'
            },
            {
                id: 'winback',
                name: 'Win-Back Strategy',
                agent: 'general',
                prompt: 'Based on everything in these emails AND your previous analysis passes (timeline, pressure tactics, profiles, financials), create a CONCRETE win-back strategy:\n\n1. ROOT CAUSE SUMMARY: In 3 sentences, why did we lose them?\n2. WHAT THEY VALUED: What did they actually appreciate about working with us?\n3. WHAT THEY HATED: What were their consistent pain points?\n4. COMPETITIVE POSITION: What would make them choose us over their current supplier?\n5. APPROACH PLAN:\n   - WHO to contact first (and why that person)\n   - WHEN (timing considerations based on their business cycle)\n   - HOW (email, call, in-person meeting?)\n   - WHAT to say (draft an opening message)\n   - WHAT TO OFFER (specific value proposition addressing their known pain points)\n6. RED LINES: What should we NOT agree to if they come back? What terms caused problems before?\n7. SUCCESS METRICS: How will we know the re-engagement is working?\n\nBe specific. Reference actual names, actual issues, actual quotes from the emails.'
            }
        ];

        // ============================================
        // TOKEN ESTIMATION
        // ============================================
        const MODEL_LIMITS = {
            'claude-opus-4-6': 200000,
            'claude-sonnet-4-6': 200000,
            'claude-sonnet-4-5-20250929': 200000,
            'claude-3-5-sonnet-20241022': 200000,
            'claude-opus-4-5-20250929': 200000,
            'claude-3-opus-20240229': 200000,
            'claude-3-5-haiku-20241022': 200000,
            'gpt-4o': 128000,
            'gpt-4o-mini': 128000,
            'gpt-4-turbo': 128000,
            'gpt-4.1': 1000000,


1430→                                    <option value="300">300s</option>
  1431→                                </select>
  1432→                                (skip slow providers after this)
  1433→
  1434→

  1435→

  1436→
  1437→
  1438→

  1439→                        <button class="btn btn-primary" id="submit-ai-btn" onclick="submitToAI()" style="flex:1;">
  1440→                            Send to AI
  1441→                        </button>
  1442→                        <button class="btn" id="deep-analysis-btn" onclick="runDeepAnalysis()" style="flex:1;background:linear-gradient(135deg,#8b5cf6,#3b82f6);color:white;font-weight:600;">
  1443→                            Deep Analysis (5-Pass)
  1444→                        </button>
  1445→

  1446→

  1447→

  1448→

  1449→

  1450→
  1451→
  1452→

  1453→

  1454→

<option value="300">300s</option>
                                </select>
                                (skip slow providers after this)

                        <button class="btn btn-primary" id="submit-ai-btn" onclick="submitToAI()" style="flex:1;">
                            Send to AI
                        </button>
                        <button class="btn" id="deep-analysis-btn" onclick="runDeepAnalysis()" style="flex:1;background:linear-gradient(135deg,#8b5cf6,#3b82f6);color:white;font-weight:600;">
                            Deep Analysis (5-Pass)
                        </button>


Now I need to read the runDeepAnalysis() function and loadDeepAnalysis() function to understand the current implementation. Let me also read the save_ai_response and load_deep_analysis API endpoints.


Now let me read the `runDeepAnalysis()` and `loadDeepAnalysis()` functions, plus the API endpoints.


3079→        async function runDeepAnalysis() {
  3080→            // Validate providers selected
  3081→            var selectedProvidersList = getSelectedProviders();
  3082→            if (selectedProvidersList.length === 0) {
  3083→                alert('Please select at least one AI provider.');
  3084→                return;
  3085→            }
  3086→
  3087→            // Build models map
  3088→            var modelsMap = {};
  3089→            selectedProvidersList.forEach(function(provider) {
  3090→                var modelSelect = document.getElementById('model_' + provider);
  3091→                modelsMap[provider] = modelSelect ? modelSelect.value : '';
  3092→            });
  3093→
  3094→            // Confirm with user
  3095→            var passNames = DEEP_ANALYSIS_PASSES.map(function(p, i) { return (i+1) + '. ' + p.name; }).join('\n');
  3096→            if (!confirm('Run Deep Analysis with ' + selectedProvidersList.length + ' AI provider(s)?\n\n' + passNames + '\n\nThis will run 5 sequential passes. Each pass builds on the previous conversation history.\n\nEstimated time: 3-10 minutes depending on content size and providers.')) {
  3097→                return;
  3098→            }
  3099→
  3100→            // Get content settings
  3101→            var contentMode = document.getElementById('content-mode').value;
  3102→            var additionalThreads = getSelectedThreads();
  3103→            var contextThreadIds = contextThreads.map(function(ct) { return ct.threadId; });
  3104→            var allAdditionalThreads = additionalThreads.concat(contextThreadIds);
  3105→            var context = document.getElementById('ai-context').value.trim();
  3106→            var timeoutSec = parseInt(document.getElementById('provider-timeout').value) || 120;
  3107→            var modelLimit = getSmallestModelLimit();
  3108→
  3109→            // Show deep analysis container and loading
  3110→            var daContainer = document.getElementById('deep-analysis-container');
  3111→            var daResults = document.getElementById('deep-analysis-results');
  3112→            var daProgress = document.getElementById('deep-analysis-progress');
  3113→            daContainer.style.display = 'block';
  3114→            daResults.innerHTML = '';
  3115→            daContainer.scrollIntoView({ behavior: 'smooth' });
  3116→
  3117→            // Disable buttons
  3118→            document.getElementById('submit-ai-btn').disabled = true;
  3119→            document.getElementById('deep-analysis-btn').disabled = true;
  3120→            document.getElementById('loading-overlay').classList.add('active');
  3121→
  3122→            try {
  3123→                // ---- BUILD BASE CONTENT ONCE ----
  3124→                document.getElementById('loading-message').textContent = 'Building email content...';
  3125→
  3126→                var memoryBlock = '';
  3127→                if (contactMemories.length > 0 && primaryContactName) {
  3128→                    memoryBlock = '=== KNOWN FACTS ABOUT ' + primaryContactName.toUpperCase() + ' ===\n';
  3129→                    contactMemories.forEach(function(m) {
  3130→                        memoryBlock += '- ' + (m.fact || m) + '\n';
  3131→                    });
  3132→                    memoryBlock += '=== END KNOWN FACTS ===\n\n';
  3133→                }
  3134→
  3135→                var baseEmailContent = memoryBlock + buildEmailContent();
  3136→
  3137→                // Fetch additional thread content
  3138→                if (allAdditionalThreads.length > 0) {
  3139→                    for (var i = 0; i < allAdditionalThreads.length; i++) {
  3140→                        var tid = allAdditionalThreads[i];
  3141→                        document.getElementById('loading-message').textContent = 'Loading additional thread ' + (i + 1) + '/' + allAdditionalThreads.length + '...';
  3142→                        try {
  3143→                            var threadResp = await fetch('api.php?action=thread_for_ai&thread_id=' + tid);
  3144→                            if (!threadResp.ok) continue;
  3145→                            var thread = await threadResp.json();
  3146→                            if (thread.emails && thread.emails.length > 0) {
  3147→                                baseEmailContent += '\n\n--- ADDITIONAL THREAD ' + (i + 1) + ' OF ' + allAdditionalThreads.length + ' ---\n';
  3148→                                baseEmailContent += 'Subject: ' + (thread.emails[0].subject || '(No Subject)') + '\n\n';
  3149→                                baseEmailContent += processAdditionalThreadContent(thread.emails, 'full');
  3150→                            }
  3151→                        } catch (fetchErr) {
  3152→                            console.warn('Error fetching thread ' + tid + ':', fetchErr);
  3153→                        }
  3154→                    }
  3155→                }
  3156→
  3157→                console.log('Deep Analysis: Base content built, ' + baseEmailContent.length + ' chars');
  3158→
  3159→                // ---- RUN EACH PASS SEQUENTIALLY ----
  3160→                for (var passIdx = 0; passIdx < DEEP_ANALYSIS_PASSES.length; passIdx++) {
  3161→                    var pass = DEEP_ANALYSIS_PASSES[passIdx];
  3162→                    var passNum = passIdx + 1;
  3163→                    var passAgent = AI_AGENTS[pass.agent];
  3164→
  3165→                    daProgress.textContent = 'Pass ' + passNum + '/' + DEEP_ANALYSIS_PASSES.length;
  3166→                    document.getElementById('loading-message').textContent = 'Pass ' + passNum + '/5: ' + pass.name + '...';
  3167→
  3168→                    // Add pass progress placeholder to results
  3169→                    var passSection = document.createElement('div');
  3170→                    passSection.id = 'deep-pass-' + pass.id;
  3171→                    passSection.style.cssText = 'margin-bottom:20px;border:1px solid #e5e7eb;border-radius:8px;overflow:hidden;';
  3172→                    passSection.innerHTML = '
' +
  3173→                        'Pass ' + passNum + ': ' + escapeHtml(pass.name) + '' +
  3174→                        'Agent: ' + escapeHtml(passAgent.icon + ' ' + passAgent.name) + '' +
  3175→                        '
' +
  3176→                        '

Running analysis...

';
  3177→                    daResults.appendChild(passSection);
  3178→
  3179→                    // Build full content for this pass
  3180→                    var agentPrompt = '=== AI AGENT INSTRUCTIONS ===\n' + passAgent.systemPrompt + '\n=== END AGENT INSTRUCTIONS ===\n\n';
  3181→                    var fullContent = agentPrompt + baseEmailContent;
  3182→
  3183→                    // Add conversation history (builds up across passes)
  3184→                    var conversationContext = buildConversationContext();
  3185→                    if (conversationContext) {
  3186→                        fullContent += conversationContext;
  3187→                    }
  3188→
  3189→                    // Add the pass question
  3190→                    fullContent += '\n\nCURRENT USER QUESTION:\n' + pass.prompt;
  3191→
  3192→                    // Add user context if provided
  3193→                    if (context) {
  3194→                        fullContent += '\n\nADDITIONAL CONTEXT:\n' + context;
  3195→                    }
  3196→
  3197→                    // Truncate to fit model limit
  3198→                    var maxChars = Math.floor(modelLimit * 3.5 * 0.85);
  3199→                    if (fullContent.length > maxChars) {
  3200→                        fullContent = fullContent.substring(0, maxChars) + '\n\n...(Content truncated to fit model context limit)';
  3201→                    }
  3202→
  3203→                    var finalTokens = Math.ceil(fullContent.length / 3.5);
  3204→
  3205→                    // Log
  3206→                    logAiDebug({
  3207→                        type: 'deep_analysis_pass',
  3208→                        pass: passNum,
  3209→                        pass_name: pass.name,
  3210→                        agent: pass.agent,
  3211→                        thread_id: currentThreadId,
  3212→                        providers: selectedProvidersList,
  3213→                        models: modelsMap,
  3214→                        content_length: fullContent.length,
  3215→                        estimated_tokens: finalTokens,
  3216→                        context_threads: allAdditionalThreads.length
  3217→                    });
  3218→
  3219→                    // Build request
  3220→                    var requestBody = {
  3221→                        user_content: fullContent,
  3222→                        providers: selectedProvidersList
  3223→                    };
  3224→                    for (var provider in modelsMap) {
  3225→                        requestBody['model_' + provider] = modelsMap[provider];
  3226→                    }
  3227→
  3228→                    // Send to AI
  3229→                    document.getElementById('loading-message').textContent = 'Pass ' + passNum + '/5: ' + pass.name + ' — sending ~' + finalTokens.toLocaleString() + ' tokens to ' + selectedProvidersList.length + ' AI(s)...';
  3230→
  3231→                    try {
  3232→                        var response = await fetchWithTimeout('../aiapi/api_opus/api/query.php', {
  3233→                            method: 'POST',
  3234→                            headers: { 'Content-Type': 'application/json' },
  3235→                            body: JSON.stringify(requestBody)
  3236→                        }, timeoutSec * 1000);
  3237→
  3238→                        if (!response.ok) {
  3239→                            throw new Error('HTTP ' + response.status);
  3240→                        }
  3241→
  3242→                        var data = JSON.parse(await response.text());
  3243→
  3244→                        // Display results for this pass
  3245→                        var passContentEl = passSection.querySelector('.deep-pass-content');
  3246→                        var passHtml = '';
  3247→
  3248→                        if (data.success) {
  3249→                            var firstProvider = null;
  3250→                            var firstResponse = null;
  3251→
  3252→                            for (var pi = 0; pi < selectedProvidersList.length; pi++) {
  3253→                                var prov = selectedProvidersList[pi];
  3254→                                var provResponse = data.responses[prov + '_response'];
  3255→                                var provConfig = providers[prov] || { name: prov };
  3256→
  3257→                                if (provResponse && provResponse.success) {
  3258→                                    if (!firstProvider) {
  3259→                                        firstProvider = prov;
  3260→                                        firstResponse = provResponse;
  3261→                                    }
  3262→
  3263→                                    passHtml += '
';
  3264→                                    passHtml += '
';
  3265→                                    passHtml += '' + escapeHtml(provConfig.name) + '';
  3266→                                    passHtml += '' + escapeHtml(provResponse.model || '') + ' | ' + (provResponse.request_time ? provResponse.request_time.toFixed(1) + 's' : '') + ' | $' + (provResponse.cost ? provResponse.cost.toFixed(4) : '0') + '';
  3267→                                    passHtml += '
';
  3268→                                    passHtml += '
' + escapeHtml(provResponse.response) + '
';
  3269→                                    passHtml += '
';
  3270→
  3271→                                    // Save to MongoDB
  3272→                                    await saveAIResponse({
  3273→                                        thread_ids: [currentThreadId].concat(allAdditionalThreads),
  3274→                                        contact_id: primaryContactId,
  3275→                                        question: pass.prompt,
  3276→                                        context: context,
  3277→                                        agent: pass.agent,
  3278→                                        content_mode: contentMode,
  3279→                                        content_sent: fullContent,
  3280→                                        content_length: fullContent.length,
  3281→                                        estimated_tokens: finalTokens,
  3282→                                        provider: prov,
  3283→                                        model: modelsMap[prov],
  3284→                                        query_id: data.query_id,
  3285→                                        response: provResponse,
  3286→                                        total_cost: provResponse.cost || 0,
  3287→                                        all_providers: selectedProvidersList,
  3288→                                        deep_analysis_pass: passNum,
  3289→                                        deep_analysis_name: pass.name
  3290→                                    });
  3291→                                } else if (provResponse) {
  3292→                                    passHtml += '
';
  3293→                                    passHtml += '' + escapeHtml(provConfig.name) + ' failed: ' + escapeHtml(provResponse.error || 'Unknown error') + '
';
  3294→                                }
  3295→                            }
  3296→
  3297→                            // Add to conversation history (first successful)
  3298→                            if (firstProvider && firstResponse) {
  3299→                                addToConversation(pass.prompt, firstResponse.response, firstProvider, modelsMap[firstProvider], context);
  3300→                            }
  3301→
  3302→                            // Update pass header with success
  3303→                            var passHeader = passSection.querySelector('div:first-child');
  3304→                            passHeader.style.background = '#f0fdf4';
  3305→                            passHeader.style.borderBottom = '1px solid #86efac';
  3306→                        } else {
  3307→                            passHtml = '
All providers failed for this pass.
';
  3308→                            var passHeader2 = passSection.querySelector('div:first-child');
  3309→                            passHeader2.style.background = '#fef2f2';
  3310→                        }
  3311→
  3312→                        passContentEl.innerHTML = passHtml;
  3313→
  3314→                    } catch (passErr) {
  3315→                        var passContentEl2 = passSection.querySelector('.deep-pass-content');
  3316→                        passContentEl2.innerHTML = '
Error: ' + escapeHtml(passErr.message) + '
';
  3317→                        var passHeader3 = passSection.querySelector('div:first-child');
  3318→                        passHeader3.style.background = '#fef2f2';
  3319→                    }
  3320→
  3321→                    // Scroll to latest result
  3322→                    passSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
  3323→
  3324→                    // Brief pause between passes to avoid rate limiting
  3325→                    if (passIdx < DEEP_ANALYSIS_PASSES.length - 1) {
  3326→                        document.getElementById('loading-message').textContent = 'Pass ' + passNum + ' complete. Starting next pass...';
  3327→                        await new Promise(function(resolve) { setTimeout(resolve, 2000); });
  3328→                    }
  3329→                }
  3330→
  3331→                // All passes complete
  3332→                daProgress.textContent = 'Complete (5/5)';
  3333→                document.getElementById('loading-message').textContent = 'Deep Analysis complete!';
  3334→
  3335→                // Add summary header
  3336→                var summaryDiv = document.createElement('div');
  3337→                summaryDiv.style.cssText = 'margin-top:15px;padding:15px;background:linear-gradient(135deg,#f0fdf4,#ecfeff);border-radius:8px;border:1px solid #86efac;';
  3338→                summaryDiv.innerHTML = 'Deep Analysis Complete
' +
  3339→                    '5 passes completed with ' + selectedProvidersList.length + ' provider(s). Results saved to AI responses. Use "Generate Chart" on any pass for visualization.';
  3340→                daResults.appendChild(summaryDiv);
  3341→
  3342→            } catch (err) {
  3343→                daProgress.textContent = 'Error';
  3344→                alert('Deep Analysis error: ' + err.message);
  3345→            } finally {
  3346→                document.getElementById('loading-overlay').classList.remove('active');
  3347→                document.getElementById('submit-ai-btn').disabled = false;
  3348→                document.getElementById('deep-analysis-btn').disabled = false;
  3349→            }
  3350→        }
  3351→
  3352→        // Load saved Deep Analysis from MongoDB
  3353→        async function loadDeepAnalysis() {
  3354→            var daContainer = document.getElementById('deep-analysis-container');
  3355→            var daResults = document.getElementById('deep-analysis-results');
  3356→            var daProgress = document.getElementById('deep-analysis-progress');
  3357→
  3358→            daContainer.style.display = 'block';

async function runDeepAnalysis() {
            // Validate providers selected
            var selectedProvidersList = getSelectedProviders();
            if (selectedProvidersList.length === 0) {
                alert('Please select at least one AI provider.');
                return;
            }

            // Build models map
            var modelsMap = {};
            selectedProvidersList.forEach(function(provider) {
                var modelSelect = document.getElementById('model_' + provider);
                modelsMap[provider] = modelSelect ? modelSelect.value : '';
            });

            // Confirm with user
            var passNames = DEEP_ANALYSIS_PASSES.map(function(p, i) { return (i+1) + '. ' + p.name; }).join('\n');
            if (!confirm('Run Deep Analysis with ' + selectedProvidersList.length + ' AI provider(s)?\n\n' + passNames + '\n\nThis will run 5 sequential passes. Each pass builds on the previous conversation history.\n\nEstimated time: 3-10 minutes depending on content size and providers.')) {
                return;
            }

            // Get content settings
            var contentMode = document.getElementById('content-mode').value;
            var additionalThreads = getSelectedThreads();
            var contextThreadIds = contextThreads.map(function(ct) { return ct.threadId; });
            var allAdditionalThreads = additionalThreads.concat(contextThreadIds);
            var context = document.getElementById('ai-context').value.trim();
            var timeoutSec = parseInt(document.getElementById('provider-timeout').value) || 120;
            var modelLimit = getSmallestModelLimit();

            // Show deep analysis container and loading
            var daContainer = document.getElementById('deep-analysis-container');
            var daResults = document.getElementById('deep-analysis-results');
            var daProgress = document.getElementById('deep-analysis-progress');
            daContainer.style.display = 'block';
            daResults.innerHTML = '';
            daContainer.scrollIntoView({ behavior: 'smooth' });

            // Disable buttons
            document.getElementById('submit-ai-btn').disabled = true;
            document.getElementById('deep-analysis-btn').disabled = true;
            document.getElementById('loading-overlay').classList.add('active');

            try {
                // ---- BUILD BASE CONTENT ONCE ----
                document.getElementById('loading-message').textContent = 'Building email content...';

                var memoryBlock = '';
                if (contactMemories.length > 0 && primaryContactName) {
                    memoryBlock = '=== KNOWN FACTS ABOUT ' + primaryContactName.toUpperCase() + ' ===\n';
                    contactMemories.forEach(function(m) {
                        memoryBlock += '- ' + (m.fact || m) + '\n';
                    });
                    memoryBlock += '=== END KNOWN FACTS ===\n\n';
                }

                var baseEmailContent = memoryBlock + buildEmailContent();

                // Fetch additional thread content
                if (allAdditionalThreads.length > 0) {
                    for (var i = 0; i < allAdditionalThreads.length; i++) {
                        var tid = allAdditionalThreads[i];
                        document.getElementById('loading-message').textContent = 'Loading additional thread ' + (i + 1) + '/' + allAdditionalThreads.length + '...';
                        try {
                            var threadResp = await fetch('api.php?action=thread_for_ai&thread_id=' + tid);
                            if (!threadResp.ok) continue;
                            var thread = await threadResp.json();
                            if (thread.emails && thread.emails.length > 0) {
                                baseEmailContent += '\n\n--- ADDITIONAL THREAD ' + (i + 1) + ' OF ' + allAdditionalThreads.length + ' ---\n';
                                baseEmailContent += 'Subject: ' + (thread.emails[0].subject || '(No Subject)') + '\n\n';
                                baseEmailContent += processAdditionalThreadContent(thread.emails, 'full');
                            }
                        } catch (fetchErr) {
                            console.warn('Error fetching thread ' + tid + ':', fetchErr);
                        }
                    }
                }

                console.log('Deep Analysis: Base content built, ' + baseEmailContent.length + ' chars');

                // ---- RUN EACH PASS SEQUENTIALLY ----
                for (var passIdx = 0; passIdx < DEEP_ANALYSIS_PASSES.length; passIdx++) {
                    var pass = DEEP_ANALYSIS_PASSES[passIdx];
                    var passNum = passIdx + 1;
                    var passAgent = AI_AGENTS[pass.agent];

                    daProgress.textContent = 'Pass ' + passNum + '/' + DEEP_ANALYSIS_PASSES.length;
                    document.getElementById('loading-message').textContent = 'Pass ' + passNum + '/5: ' + pass.name + '...';

                    // Add pass progress placeholder to results
                    var passSection = document.createElement('div');
                    passSection.id = 'deep-pass-' + pass.id;
                    passSection.style.cssText = 'margin-bottom:20px;border:1px solid #e5e7eb;border-radius:8px;overflow:hidden;';
                    passSection.innerHTML = '
' +
                        'Pass ' + passNum + ': ' + escapeHtml(pass.name) + '' +
                        'Agent: ' + escapeHtml(passAgent.icon + ' ' + passAgent.name) + '' +
                        '
' +
                        '

Running analysis...

';
                    daResults.appendChild(passSection);

                    // Build full content for this pass
                    var agentPrompt = '=== AI AGENT INSTRUCTIONS ===\n' + passAgent.systemPrompt + '\n=== END AGENT INSTRUCTIONS ===\n\n';
                    var fullContent = agentPrompt + baseEmailContent;

                    // Add conversation history (builds up across passes)
                    var conversationContext = buildConversationContext();
                    if (conversationContext) {
                        fullContent += conversationContext;
                    }

                    // Add the pass question
                    fullContent += '\n\nCURRENT USER QUESTION:\n' + pass.prompt;

                    // Add user context if provided
                    if (context) {
                        fullContent += '\n\nADDITIONAL CONTEXT:\n' + context;
                    }

                    // Truncate to fit model limit
                    var maxChars = Math.floor(modelLimit * 3.5 * 0.85);
                    if (fullContent.length > maxChars) {
                        fullContent = fullContent.substring(0, maxChars) + '\n\n...(Content truncated to fit model context limit)';
                    }

                    var finalTokens = Math.ceil(fullContent.length / 3.5);

                    // Log
                    logAiDebug({
                        type: 'deep_analysis_pass',
                        pass: passNum,
                        pass_name: pass.name,
                        agent: pass.agent,
                        thread_id: currentThreadId,
                        providers: selectedProvidersList,
                        models: modelsMap,
                        content_length: fullContent.length,
                        estimated_tokens: finalTokens,
                        context_threads: allAdditionalThreads.length
                    });

                    // Build request
                    var requestBody = {
                        user_content: fullContent,
                        providers: selectedProvidersList
                    };
                    for (var provider in modelsMap) {
                        requestBody['model_' + provider] = modelsMap[provider];
                    }

                    // Send to AI
                    document.getElementById('loading-message').textContent = 'Pass ' + passNum + '/5: ' + pass.name + ' — sending ~' + finalTokens.toLocaleString() + ' tokens to ' + selectedProvidersList.length + ' AI(s)...';

                    try {
                        var response = await fetchWithTimeout('../aiapi/api_opus/api/query.php', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify(requestBody)
                        }, timeoutSec * 1000);

                        if (!response.ok) {
                            throw new Error('HTTP ' + response.status);
                        }

                        var data = JSON.parse(await response.text());

                        // Display results for this pass
                        var passContentEl = passSection.querySelector('.deep-pass-content');
                        var passHtml = '';

                        if (data.success) {
                            var firstProvider = null;
                            var firstResponse = null;

                            for (var pi = 0; pi < selectedProvidersList.length; pi++) {
                                var prov = selectedProvidersList[pi];
                                var provResponse = data.responses[prov + '_response'];
                                var provConfig = providers[prov] || { name: prov };

                                if (provResponse && provResponse.success) {
                                    if (!firstProvider) {
                                        firstProvider = prov;
                                        firstResponse = provResponse;
                                    }

                                    passHtml += '
';
                                    passHtml += '
';
                                    passHtml += '' + escapeHtml(provConfig.name) + '';
                                    passHtml += '' + escapeHtml(provResponse.model || '') + ' | ' + (provResponse.request_time ? provResponse.request_time.toFixed(1) + 's' : '') + ' | $' + (provResponse.cost ? provResponse.cost.toFixed(4) : '0') + '';
                                    passHtml += '
';
                                    passHtml += '
' + escapeHtml(provResponse.response) + '
';
                                    passHtml += '
';

                                    // Save to MongoDB
                                    await saveAIResponse({
                                        thread_ids: [currentThreadId].concat(allAdditionalThreads),
                                        contact_id: primaryContactId,
                                        question: pass.prompt,
                                        context: context,
                                        agent: pass.agent,
                                        content_mode: contentMode,
                                        content_sent: fullContent,
                                        content_length: fullContent.length,
                                        estimated_tokens: finalTokens,
                                        provider: prov,
                                        model: modelsMap[prov],
                                        query_id: data.query_id,
                                        response: provResponse,
                                        total_cost: provResponse.cost || 0,
                                        all_providers: selectedProvidersList,
                                        deep_analysis_pass: passNum,
                                        deep_analysis_name: pass.name
                                    });
                                } else if (provResponse) {
                                    passHtml += '
';
                                    passHtml += '' + escapeHtml(provConfig.name) + ' failed: ' + escapeHtml(provResponse.error || 'Unknown error') + '
';
                                }
                            }

                            // Add to conversation history (first successful)
                            if (firstProvider && firstResponse) {
                                addToConversation(pass.prompt, firstResponse.response, firstProvider, modelsMap[firstProvider], context);
                            }

                            // Update pass header with success
                            var passHeader = passSection.querySelector('div:first-child');
                            passHeader.style.background = '#f0fdf4';
                            passHeader.style.borderBottom = '1px solid #86efac';
                        } else {
                            passHtml = '
All providers failed for this pass.
';
                            var passHeader2 = passSection.querySelector('div:first-child');
                            passHeader2.style.background = '#fef2f2';
                        }

                        passContentEl.innerHTML = passHtml;

                    } catch (passErr) {
                        var passContentEl2 = passSection.querySelector('.deep-pass-content');
                        passContentEl2.innerHTML = '
Error: ' + escapeHtml(passErr.message) + '
';
                        var passHeader3 = passSection.querySelector('div:first-child');
                        passHeader3.style.background = '#fef2f2';
                    }

                    // Scroll to latest result
                    passSection.scrollIntoView({ behavior: 'smooth', block: 'start' });

                    // Brief pause between passes to avoid rate limiting
                    if (passIdx < DEEP_ANALYSIS_PASSES.length - 1) {
                        document.getElementById('loading-message').textContent = 'Pass ' + passNum + ' complete. Starting next pass...';
                        await new Promise(function(resolve) { setTimeout(resolve, 2000); });
                    }
                }

                // All passes complete
                daProgress.textContent = 'Complete (5/5)';
                document.getElementById('loading-message').textContent = 'Deep Analysis complete!';

                // Add summary header
                var summaryDiv = document.createElement('div');
                summaryDiv.style.cssText = 'margin-top:15px;padding:15px;background:linear-gradient(135deg,#f0fdf4,#ecfeff);border-radius:8px;border:1px solid #86efac;';
                summaryDiv.innerHTML = 'Deep Analysis Complete
' +
                    '5 passes completed with ' + selectedProvidersList.length + ' provider(s). Results saved to AI responses. Use "Generate Chart" on any pass for visualization.';
                daResults.appendChild(summaryDiv);

            } catch (err) {
                daProgress.textContent = 'Error';
                alert('Deep Analysis error: ' + err.message);
            } finally {
                document.getElementById('loading-overlay').classList.remove('active');
                document.getElementById('submit-ai-btn').disabled = false;
                document.getElementById('deep-analysis-btn').disabled = false;
            }
        }

        // Load saved Deep Analysis from MongoDB
        async function loadDeepAnalysis() {
            var daContainer = document.getElementById('deep-analysis-container');
            var daResults = document.getElementById('deep-analysis-results');
            var daProgress = document.getElementById('deep-analysis-progress');

            daContainer.style.display = 'block';


3353→        async function loadDeepAnalysis() {
  3354→            var daContainer = document.getElementById('deep-analysis-container');
  3355→            var daResults = document.getElementById('deep-analysis-results');
  3356→            var daProgress = document.getElementById('deep-analysis-progress');
  3357→
  3358→            daContainer.style.display = 'block';
  3359→            daResults.innerHTML = '
Loading deep analysis...
';
  3360→            daProgress.textContent = 'Loading...';
  3361→            daContainer.scrollIntoView({ behavior: 'smooth' });
  3362→
  3363→            try {
  3364→                var resp = await fetch('api.php?action=load_deep_analysis&thread_id=' + encodeURIComponent(currentThreadId));
  3365→                var data = await resp.json();
  3366→
  3367→                if (!data.success || !data.passes || data.passes.length === 0) {
  3368→                    daResults.innerHTML = '
No deep analysis found for this thread.
';
  3369→                    daProgress.textContent = '';
  3370→                    return;
  3371→                }
  3372→
  3373→                daResults.innerHTML = '';
  3374→                daProgress.textContent = data.passes.length + ' passes loaded';
  3375→
  3376→                data.passes.forEach(function(pass) {
  3377→                    var passAgent = AI_AGENTS[pass.agent] || { name: pass.agent, icon: '' };
  3378→
  3379→                    var passSection = document.createElement('div');
  3380→                    passSection.style.cssText = 'margin-bottom:20px;border:1px solid #e5e7eb;border-radius:8px;overflow:hidden;';
  3381→
  3382→                    var passHtml = '
' +
  3383→                        'Pass ' + pass.pass + ': ' + escapeHtml(pass.name) + '' +
  3384→                        'Agent: ' + escapeHtml(passAgent.icon + ' ' + passAgent.name) + '' +
  3385→                        '

';
  3386→
  3387→                    pass.responses.forEach(function(r) {
  3388→                        passHtml += '
';
  3389→                        passHtml += '
';
  3390→                        passHtml += '' + escapeHtml(r.provider) + '';
  3391→                        passHtml += '' + escapeHtml(r.model) + ' | ' + (r.request_time ? parseFloat(r.request_time).toFixed(1) + 's' : '') + ' | $' + (r.cost ? parseFloat(r.cost).toFixed(4) : '0') + '';
  3392→                        passHtml += '
';
  3393→                        passHtml += '
' + escapeHtml(r.response) + '
';
  3394→                        passHtml += '
';
  3395→                    });
  3396→
  3397→                    passHtml += '
';
  3398→                    passSection.innerHTML = passHtml;
  3399→                    daResults.appendChild(passSection);
  3400→                });
  3401→
  3402→                // Add info footer
  3403→                var footer = document.createElement('div');
  3404→                footer.style.cssText = 'margin-top:15px;padding:15px;background:linear-gradient(135deg,#f0fdf4,#ecfeff);border-radius:8px;border:1px solid #86efac;';
  3405→                footer.innerHTML = 'Deep Analysis Loaded
' +
  3406→                    '' + data.total_responses + ' saved responses across ' + data.passes.length + ' passes.';
  3407→                daResults.appendChild(footer);
  3408→
  3409→            } catch (err) {
  3410→                daResults.innerHTML = '
Error loading deep analysis: ' + escapeHtml(err.message) + '
';
  3411→                daProgress.textContent = 'Error';
  3412→            }
  3413→        }
  3414→
  3415→        // Submit to AI
  3416→        async function submitToAI() {
  3417→            var selectedProvidersList = getSelectedProviders();
  3418→
  3419→            if (selectedProvidersList.length === 0) {
  3420→                alert('Please select at least one AI provider');
  3421→                return;
  3422→            }

async function loadDeepAnalysis() {
            var daContainer = document.getElementById('deep-analysis-container');
            var daResults = document.getElementById('deep-analysis-results');
            var daProgress = document.getElementById('deep-analysis-progress');

            daContainer.style.display = 'block';
            daResults.innerHTML = '
Loading deep analysis...
';
            daProgress.textContent = 'Loading...';
            daContainer.scrollIntoView({ behavior: 'smooth' });

            try {
                var resp = await fetch('api.php?action=load_deep_analysis&thread_id=' + encodeURIComponent(currentThreadId));
                var data = await resp.json();

                if (!data.success || !data.passes || data.passes.length === 0) {
                    daResults.innerHTML = '
No deep analysis found for this thread.
';
                    daProgress.textContent = '';
                    return;
                }

                daResults.innerHTML = '';
                daProgress.textContent = data.passes.length + ' passes loaded';

                data.passes.forEach(function(pass) {
                    var passAgent = AI_AGENTS[pass.agent] || { name: pass.agent, icon: '' };

                    var passSection = document.createElement('div');
                    passSection.style.cssText = 'margin-bottom:20px;border:1px solid #e5e7eb;border-radius:8px;overflow:hidden;';

                    var passHtml = '
' +
                        'Pass ' + pass.pass + ': ' + escapeHtml(pass.name) + '' +
                        'Agent: ' + escapeHtml(passAgent.icon + ' ' + passAgent.name) + '' +
                        '

';

                    pass.responses.forEach(function(r) {
                        passHtml += '
';
                        passHtml += '
';
                        passHtml += '' + escapeHtml(r.provider) + '';
                        passHtml += '' + escapeHtml(r.model) + ' | ' + (r.request_time ? parseFloat(r.request_time).toFixed(1) + 's' : '') + ' | $' + (r.cost ? parseFloat(r.cost).toFixed(4) : '0') + '';
                        passHtml += '
';
                        passHtml += '
' + escapeHtml(r.response) + '
';
                        passHtml += '
';
                    });

                    passHtml += '
';
                    passSection.innerHTML = passHtml;
                    daResults.appendChild(passSection);
                });

                // Add info footer
                var footer = document.createElement('div');
                footer.style.cssText = 'margin-top:15px;padding:15px;background:linear-gradient(135deg,#f0fdf4,#ecfeff);border-radius:8px;border:1px solid #86efac;';
                footer.innerHTML = 'Deep Analysis Loaded
' +
                    '' + data.total_responses + ' saved responses across ' + data.passes.length + ' passes.';
                daResults.appendChild(footer);

            } catch (err) {
                daResults.innerHTML = '
Error loading deep analysis: ' + escapeHtml(err.message) + '
';
                daProgress.textContent = 'Error';
            }
        }

        // Submit to AI
        async function submitToAI() {
            var selectedProvidersList = getSelectedProviders();

            if (selectedProvidersList.length === 0) {
                alert('Please select at least one AI provider');
                return;
            }


  4790→                'context' => $jsonData['context'] ?? null,
  4791→                'content_mode' => $jsonData['content_mode'] ?? 'full',
  4792→                'content_sent' => $jsonData['content_sent'] ?? null,
  4793→                'content_length' => $jsonData['content_length'] ?? 0,
  4794→                'estimated_tokens' => $jsonData['estimated_tokens'] ?? 0,
  4795→                'provider' => $jsonData['provider'] ?? 'unknown',
  4796→                'model' => $jsonData['model'] ?? 'unknown',
  4797→                'all_providers' => $jsonData['all_providers'] ?? [],
  4798→                'query_id' => $jsonData['query_id'] ?? null,
  4799→                'response' => $jsonData['response'] ?? null,
  4800→                'total_cost' => $jsonData['total_cost'] ?? 0,
  4801→                'agent' => $jsonData['agent'] ?? null,
  4802→                'deep_analysis_pass' => isset($jsonData['deep_analysis_pass']) ? (int)$jsonData['deep_analysis_pass'] : null,
  4803→                'deep_analysis_name' => $jsonData['deep_analysis_name'] ?? null,
  4804→                'created_at' => date('Y-m-d H:i:s')
  4805→            ];
  4806→
  4807→            // Remove null optional fields to keep documents clean
  4808→            if ($responseDoc['agent'] === null) unset($responseDoc['agent']);
  4809→            if ($responseDoc['deep_analysis_pass'] === null) unset($responseDoc['deep_analysis_pass']);
  4810→            if ($responseDoc['deep_analysis_name'] === null) unset($responseDoc['deep_analysis_name']);
  4811→
  4812→            $id = $mongo->insert('ai_query_responses', $responseDoc);
  4813→
  4814→            jsonResponse([
  4815→                'success' => true,
  4816→                'id' => $id,
  4817→                'message' => 'AI response saved'
  4818→            ]);
  4819→            break;
  4820→
  4821→        // ==========================================
  4822→        // Log AI Debug Info to File
  4823→        // ==========================================
  4824→        case 'log_ai_debug':
  4825→            if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  4826→                jsonError('POST required', 405);
  4827→            }
  4828→
  4829→            $logDir = dirname(__DIR__) . '/logs';

                'context' => $jsonData['context'] ?? null,
                'content_mode' => $jsonData['content_mode'] ?? 'full',
                'content_sent' => $jsonData['content_sent'] ?? null,
                'content_length' => $jsonData['content_length'] ?? 0,
                'estimated_tokens' => $jsonData['estimated_tokens'] ?? 0,
                'provider' => $jsonData['provider'] ?? 'unknown',
                'model' => $jsonData['model'] ?? 'unknown',
                'all_providers' => $jsonData['all_providers'] ?? [],
                'query_id' => $jsonData['query_id'] ?? null,
                'response' => $jsonData['response'] ?? null,
                'total_cost' => $jsonData['total_cost'] ?? 0,
                'agent' => $jsonData['agent'] ?? null,
                'deep_analysis_pass' => isset($jsonData['deep_analysis_pass']) ? (int)$jsonData['deep_analysis_pass'] : null,
                'deep_analysis_name' => $jsonData['deep_analysis_name'] ?? null,
                'created_at' => date('Y-m-d H:i:s')
            ];

            // Remove null optional fields to keep documents clean
            if ($responseDoc['agent'] === null) unset($responseDoc['agent']);
            if ($responseDoc['deep_analysis_pass'] === null) unset($responseDoc['deep_analysis_pass']);
            if ($responseDoc['deep_analysis_name'] === null) unset($responseDoc['deep_analysis_name']);

            $id = $mongo->insert('ai_query_responses', $responseDoc);

            jsonResponse([
                'success' => true,
                'id' => $id,
                'message' => 'AI response saved'
            ]);
            break;

        // ==========================================
        // Log AI Debug Info to File
        // ==========================================
        case 'log_ai_debug':
            if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
                jsonError('POST required', 405);
            }

            $logDir = dirname(__DIR__) . '/logs';


  4938→        case 'load_deep_analysis':
  4939→            $threadId = $_GET['thread_id'] ?? '';
  4940→            if (!$threadId) jsonError('thread_id required');
  4941→            $threadId = resolveThreadId($threadId);
  4942→
  4943→            $mongo = \EmailIntelligence\MongoDatabase::getInstance();
  4944→
  4945→            // Find all responses with deep_analysis_pass field for this thread
  4946→            $responses = $mongo->findAll('ai_query_responses', [
  4947→                'thread_ids' => $threadId,
  4948→                'deep_analysis_pass' => ['$exists' => true]
  4949→            ], [
  4950→                'sort' => ['deep_analysis_pass' => 1, 'created_at' => -1]
  4951→            ]);
  4952→
  4953→            // Fallback: if no tagged responses, detect by matching question text patterns
  4954→            if (empty($responses)) {
  4955→                // Order matters: check most specific first, win-back before pressure (since win-back mentions pressure too)
  4956→                $passSignatures = [
  4957→                    5 => ['match' => 'CONCRETE win-back strategy', 'name' => 'Win-Back Strategy', 'agent' => 'general'],
  4958→                    1 => ['match' => 'Analyze the COMPLETE email history chronologically', 'name' => 'Business Relationship Timeline', 'agent' => 'general'],
  4959→                    3 => ['match' => 'psychological and business profiles for EACH', 'name' => 'Psychological Profiles', 'agent' => 'contact_profiler'],
  4960→                    4 => ['match' => 'ALL PRICES QUOTED', 'name' => 'Financial & Business Patterns', 'agent' => 'quote_analyst'],
  4961→                    2 => ['match' => 'PRESSURE TACTICS: Where did they push unreasonable', 'name' => 'Pressure & Manipulation Detection', 'agent' => 'deception_detector'],
  4962→                ];
  4963→
  4964→                $allResponses = $mongo->findAll('ai_query_responses', [
  4965→                    'thread_ids' => $threadId
  4966→                ], [
  4967→                    'sort' => ['created_at' => 1]
  4968→                ]);
  4969→
  4970→                foreach ($allResponses as $r) {
  4971→                    $q = $r['question'] ?? '';
  4972→                    foreach ($passSignatures as $passNum => $sig) {
  4973→                        if (stripos($q, $sig['match']) !== false) {
  4974→                            $r['deep_analysis_pass'] = $passNum;
  4975→                            $r['deep_analysis_name'] = $sig['name'];
  4976→                            $r['agent'] = $r['agent'] ?? $sig['agent'];
  4977→                            $responses[] = $r;
  4978→                            break;
  4979→                        }
  4980→                    }
  4981→                }
  4982→            }
  4983→
  4984→            // Group by pass
  4985→            $passes = [];
  4986→            foreach ($responses as $r) {
  4987→                $passNum = $r['deep_analysis_pass'] ?? 0;
  4988→                if (!isset($passes[$passNum])) {
  4989→                    $passes[$passNum] = [
  4990→                        'pass' => $passNum,
  4991→                        'name' => $r['deep_analysis_name'] ?? 'Pass ' . $passNum,
  4992→                        'agent' => $r['agent'] ?? 'general',
  4993→                        'responses' => []
  4994→                    ];
  4995→                }
  4996→                $passes[$passNum]['responses'][] = [
  4997→                    '_id' => (string)$r['_id'],
  4998→                    'provider' => $r['provider'] ?? '',
  4999→                    'model' => $r['model'] ?? '',
  5000→                    'response' => $r['response']['response'] ?? '',
  5001→                    'cost' => $r['response']['cost'] ?? 0,
  5002→                    'request_time' => $r['response']['request_time'] ?? 0,
  5003→                    'created_at' => $r['created_at'] ?? ''
  5004→                ];
  5005→            }
  5006→
  5007→            // Re-index to sequential array
  5008→            ksort($passes);
  5009→            $passes = array_values($passes);
  5010→
  5011→            jsonResponse([
  5012→                'success' => true,
  5013→                'passes' => $passes,
  5014→                'total_responses' => count($responses)
  5015→            ]);
  5016→            break;
  5017→
  5018→        // ==========================================
  5019→        // Product Search - Start a new product search
  5020→        // ==========================================
  5021→        case 'startProductSearch':
  5022→            require_once dirname(__DIR__) . '/src/ProductSearch.php';

        case 'load_deep_analysis':
            $threadId = $_GET['thread_id'] ?? '';
            if (!$threadId) jsonError('thread_id required');
            $threadId = resolveThreadId($threadId);

            $mongo = \EmailIntelligence\MongoDatabase::getInstance();

            // Find all responses with deep_analysis_pass field for this thread
            $responses = $mongo->findAll('ai_query_responses', [
                'thread_ids' => $threadId,
                'deep_analysis_pass' => ['$exists' => true]
            ], [
                'sort' => ['deep_analysis_pass' => 1, 'created_at' => -1]
            ]);

            // Fallback: if no tagged responses, detect by matching question text patterns
            if (empty($responses)) {
                // Order matters: check most specific first, win-back before pressure (since win-back mentions pressure too)
                $passSignatures = [
                    5 => ['match' => 'CONCRETE win-back strategy', 'name' => 'Win-Back Strategy', 'agent' => 'general'],
                    1 => ['match' => 'Analyze the COMPLETE email history chronologically', 'name' => 'Business Relationship Timeline', 'agent' => 'general'],
                    3 => ['match' => 'psychological and business profiles for EACH', 'name' => 'Psychological Profiles', 'agent' => 'contact_profiler'],
                    4 => ['match' => 'ALL PRICES QUOTED', 'name' => 'Financial & Business Patterns', 'agent' => 'quote_analyst'],
                    2 => ['match' => 'PRESSURE TACTICS: Where did they push unreasonable', 'name' => 'Pressure & Manipulation Detection', 'agent' => 'deception_detector'],
                ];

                $allResponses = $mongo->findAll('ai_query_responses', [
                    'thread_ids' => $threadId
                ], [
                    'sort' => ['created_at' => 1]
                ]);

                foreach ($allResponses as $r) {
                    $q = $r['question'] ?? '';
                    foreach ($passSignatures as $passNum => $sig) {
                        if (stripos($q, $sig['match']) !== false) {
                            $r['deep_analysis_pass'] = $passNum;
                            $r['deep_analysis_name'] = $sig['name'];
                            $r['agent'] = $r['agent'] ?? $sig['agent'];
                            $responses[] = $r;
                            break;
                        }
                    }
                }
            }

            // Group by pass
            $passes = [];
            foreach ($responses as $r) {
                $passNum = $r['deep_analysis_pass'] ?? 0;
                if (!isset($passes[$passNum])) {
                    $passes[$passNum] = [
                        'pass' => $passNum,
                        'name' => $r['deep_analysis_name'] ?? 'Pass ' . $passNum,
                        'agent' => $r['agent'] ?? 'general',
                        'responses' => []
                    ];
                }
                $passes[$passNum]['responses'][] = [
                    '_id' => (string)$r['_id'],
                    'provider' => $r['provider'] ?? '',
                    'model' => $r['model'] ?? '',
                    'response' => $r['response']['response'] ?? '',
                    'cost' => $r['response']['cost'] ?? 0,
                    'request_time' => $r['response']['request_time'] ?? 0,
                    'created_at' => $r['created_at'] ?? ''
                ];
            }

            // Re-index to sequential array
            ksort($passes);
            $passes = array_values($passes);

            jsonResponse([
                'success' => true,
                'passes' => $passes,
                'total_responses' => count($responses)
            ]);
            break;

        // ==========================================
        // Product Search - Start a new product search
        // ==========================================
        case 'startProductSearch':
            require_once dirname(__DIR__) . '/src/ProductSearch.php';


Now I have all the context I need. Let me also read the deep analysis container HTML section to see exactly what needs to be modified.


Now let me also read the deep analysis container HTML and the Load Deep Analysis button area.


1215→

  1216→

  1217→

  1218→

  1219→

  1220→
  1221→
  1222→

  1223→

  1224→

  1225→
Deep Analysis

  1226→

  1227→
  1228→                                <button class="btn" style="background:rgba(255,255,255,0.2);color:white;border:1px solid rgba(255,255,255,0.3);" onclick="document.getElementById('deep-analysis-container').style.display='none'">Close</button>
  1229→

  1230→

  1231→

  1232→

  1233→

  1234→
  1235→
  1236→                <?php if (!empty($savedResponses)): ?>
  1237→

  1238→

  1239→
Previous AI Analyses (<?= $totalSavedResponses ?> total)

  1240→                        <?php if ($hasDeepAnalysis): ?>
  1241→                        <button class="btn" onclick="loadDeepAnalysis()" style="background:linear-gradient(135deg,#8b5cf6,#3b82f6);color:white;font-size:0.85em;">Load Deep Analysis</button>
  1242→                        <?php endif; ?>
  1243→

  1244→

  1245→                        <?php foreach ($savedResponses as $saved):
  1246→                            // Determine what to display as the "question"
  1247→                            $displayQuestion = $saved['question'] ?? 'General Analysis';
  1248→                            $hasContext = !empty($saved['context']);
  1249→                            $isDefaultQuestion = strpos($displayQuestion, 'Please analyze this email conversation') === 0;
  1250→
  1251→                            // If question is the default and user provided context, show context instead
  1252→                            if ($isDefaultQuestion && $hasContext) {
  1253→                                $displayQuestion = '[Context] ' . $saved['context'];
  1254→                            } elseif ($hasContext && !$isDefaultQuestion) {

Deep Analysis

                                <button class="btn" style="background:rgba(255,255,255,0.2);color:white;border:1px solid rgba(255,255,255,0.3);" onclick="document.getElementById('deep-analysis-container').style.display='none'">Close</button>

                <?php if (!empty($savedResponses)): ?>

Previous AI Analyses (<?= $totalSavedResponses ?> total)

                        <?php if ($hasDeepAnalysis): ?>
                        <button class="btn" onclick="loadDeepAnalysis()" style="background:linear-gradient(135deg,#8b5cf6,#3b82f6);color:white;font-size:0.85em;">Load Deep Analysis</button>
                        <?php endif; ?>

                        <?php foreach ($savedResponses as $saved):
                            // Determine what to display as the "question"
                            $displayQuestion = $saved['question'] ?? 'General Analysis';
                            $hasContext = !empty($saved['context']);
                            $isDefaultQuestion = strpos($displayQuestion, 'Please analyze this email conversation') === 0;

                            // If question is the default and user provided context, show context instead
                            if ($isDefaultQuestion && $hasContext) {
                                $displayQuestion = '[Context] ' . $saved['context'];
                            } elseif ($hasContext && !$isDefaultQuestion) {


Now I have all the context needed. Let me start implementing. I'll begin with the biggest change — replacing `DEEP_ANALYSIS_PASSES` with `DEEP_ANALYSIS_PLAYBOOKS` in thread_view.php.


Edit

        // ============================================
        // DEEP ANALYSIS — Automated 5-Pass
        // ============================================
        const DEEP_ANALYSIS_PASSES = [
            {
                id: 'timeline',
                name: 'Business Relationship Timeline',
                agent: 'general',
                prompt: 'Analyze the COMPLETE email history chronologically. Build a detailed timeline of the business relationship:\n\n1. KEY MILESTONES: When did the relationship start? What were the major projects/deals? When did things start going wrong? When did we lose them?\n2. TURNING POINTS: Identify the exact moments where the relationship shifted negatively. Quote specific emails.\n3. OUR MISTAKES: What did we do wrong? Late deliveries, missed expectations, poor communication, pricing issues? Be brutally honest.\n4. THEIR SATISFACTION CURVE: Rate their satisfaction (1-10) at each major point in the timeline.\n5. UNRESOLVED ISSUES: What was never properly addressed or closed?\n6. LAST INTERACTION: What was the tone and content of our last exchange? Did we leave the door open?'
            },
            {
                id: 'pressure',
                name: 'Pressure & Manipulation Detection',
                agent: 'deception_detector',
                prompt: 'Analyze ALL emails from the other party\'s team members for:\n\n1. PRESSURE TACTICS: Where did they push unreasonable deadlines, scope changes, or price reductions? Quote specific examples.\n2. BROKEN PROMISES from their side: Did they commit to volumes, timelines, payments that didn\'t materialize?\n3. DOUBLE STANDARDS: Did they hold us to standards they didn\'t meet themselves?\n4. ESCALATION PATTERNS: When and why did they escalate to the CEO? Was it justified or a power play?\n5. BLAME SHIFTING: Did they blame us for problems that were partially/fully their responsibility?\n6. GOOD FAITH SIGNALS: To be fair — where were they genuinely reasonable or helpful?\n\nRate each team member\'s negotiation tactics: FAIR / AGGRESSIVE / MANIPULATIVE with evidence.'
            },
            {
                id: 'profiles',
                name: 'Psychological Profiles',
                agent: 'contact_profiler',
                prompt: 'Build detailed psychological and business profiles for EACH person from the other party in these emails. For each person provide:\n\n1. NAME & ROLE (infer from email signatures and context)\n2. COMMUNICATION STYLE: Formal/casual, direct/indirect, emotional/analytical\n3. DECISION-MAKING: Do they decide alone or need approval? Fast or slow? Risk-averse?\n4. WHAT MOTIVATES THEM: Price? Quality? Relationships? Status? Control?\n5. HOW THEY HANDLE CONFLICT: Confrontational, avoidant, diplomatic, passive-aggressive?\n6. THEIR INFLUENCE: Who has real power vs who is just executing?\n7. THEIR ATTITUDE TOWARD US: Positive, neutral, negative? Did it change over time?\n8. APPROACH STRATEGY: How should we approach THIS specific person to rebuild the relationship?\n\nPay special attention to the CEO — what drives them, what frustrates them, what would win them back?'
            },
            {
                id: 'financial',
                name: 'Financial & Business Patterns',
                agent: 'quote_analyst',
                prompt: 'Analyze the complete financial and business history:\n\n1. ALL PRICES QUOTED: Every amount, every project, every change order — create a table\n2. PRICING TRENDS: Did our prices go up/down? Did they push for discounts? How much did we concede?\n3. SCOPE CREEP: Where did work expand beyond original quotes without matching price increases?\n4. PAYMENT BEHAVIOR: Were they prompt payers? Any disputes over invoices?\n5. VOLUME vs COMMITMENT: Did they promise volume that didn\'t materialize?\n6. COMPETITOR MENTIONS: Did they mention other suppliers? Use competitor pricing as leverage?\n7. PROFITABILITY ASSESSMENT: Based on the patterns, were they a profitable client or were we losing money?\n8. RE-ENGAGEMENT PRICING: What pricing strategy should we use to win them back without repeating past mistakes?'
            },
            {
                id: 'winback',
                name: 'Win-Back Strategy',
                agent: 'general',
                prompt: 'Based on everything in these emails AND your previous analysis passes (timeline, pressure tactics, profiles, financials), create a CONCRETE win-back strategy:\n\n1. ROOT CAUSE SUMMARY: In 3 sentences, why did we lose them?\n2. WHAT THEY VALUED: What did they actually appreciate about working with us?\n3. WHAT THEY HATED: What were their consistent pain points?\n4. COMPETITIVE POSITION: What would make them choose us over their current supplier?\n5. APPROACH PLAN:\n   - WHO to contact first (and why that person)\n   - WHEN (timing considerations based on their business cycle)\n   - HOW (email, call, in-person meeting?)\n   - WHAT to say (draft an opening message)\n   - WHAT TO OFFER (specific value proposition addressing their known pain points)\n6. RED LINES: What should we NOT agree to if they come back? What terms caused problems before?\n7. SUCCESS METRICS: How will we know the re-engagement is working?\n\nBe specific. Reference actual names, actual issues, actual quotes from the emails.'
            }
        ];

        // ============================================
        // DEEP ANALYSIS — Configurable Playbooks
        // ============================================
        const DEEP_ANALYSIS_PLAYBOOKS = {
            // ---- LOST CLIENT WIN-BACK ----
            'win_back': {
                name: 'Win Back Lost Client',
                description: 'Full relationship analysis + win-back strategy',
                passes: [
                    {
                        id: 'timeline',
                        name: 'Business Relationship Timeline',
                        agent: 'general',
                        prompt: 'Analyze the COMPLETE email history chronologically. Build a detailed timeline of the business relationship:\n\n1. KEY MILESTONES: When did the relationship start? What were the major projects/deals? When did things start going wrong? When did we lose them?\n2. TURNING POINTS: Identify the exact moments where the relationship shifted negatively. Quote specific emails.\n3. OUR MISTAKES: What did we do wrong? Late deliveries, missed expectations, poor communication, pricing issues? Be brutally honest.\n4. THEIR SATISFACTION CURVE: Rate their satisfaction (1-10) at each major point in the timeline.\n5. UNRESOLVED ISSUES: What was never properly addressed or closed?\n6. LAST INTERACTION: What was the tone and content of our last exchange? Did we leave the door open?'
                    },
                    {
                        id: 'pressure',
                        name: 'Pressure & Manipulation Detection',
                        agent: 'deception_detector',
                        prompt: 'Analyze ALL emails from the other party\'s team members for:\n\n1. PRESSURE TACTICS: Where did they push unreasonable deadlines, scope changes, or price reductions? Quote specific examples.\n2. BROKEN PROMISES from their side: Did they commit to volumes, timelines, payments that didn\'t materialize?\n3. DOUBLE STANDARDS: Did they hold us to standards they didn\'t meet themselves?\n4. ESCALATION PATTERNS: When and why did they escalate to the CEO? Was it justified or a power play?\n5. BLAME SHIFTING: Did they blame us for problems that were partially/fully their responsibility?\n6. GOOD FAITH SIGNALS: To be fair — where were they genuinely reasonable or helpful?\n\nRate each team member\'s negotiation tactics: FAIR / AGGRESSIVE / MANIPULATIVE with evidence.'
                    },
                    {
                        id: 'profiles',
                        name: 'Psychological Profiles',
                        agent: 'contact_profiler',
                        prompt: 'Build detailed psychological and business profiles for EACH person from the other party in these emails. For each person provide:\n\n1. NAME & ROLE (infer from email signatures and context)\n2. COMMUNICATION STYLE: Formal/casual, direct/indirect, emotional/analytical\n3. DECISION-MAKING: Do they decide alone or need approval? Fast or slow? Risk-averse?\n4. WHAT MOTIVATES THEM: Price? Quality? Relationships? Status? Control?\n5. HOW THEY HANDLE CONFLICT: Confrontational, avoidant, diplomatic, passive-aggressive?\n6. THEIR INFLUENCE: Who has real power vs who is just executing?\n7. THEIR ATTITUDE TOWARD US: Positive, neutral, negative? Did it change over time?\n8. APPROACH STRATEGY: How should we approach THIS specific person to rebuild the relationship?\n\nPay special attention to the CEO — what drives them, what frustrates them, what would win them back?'
                    },
                    {
                        id: 'financial',
                        name: 'Financial & Business Patterns',
                        agent: 'quote_analyst',
                        prompt: 'Analyze the complete financial and business history:\n\n1. ALL PRICES QUOTED: Every amount, every project, every change order — create a table\n2. PRICING TRENDS: Did our prices go up/down? Did they push for discounts? How much did we concede?\n3. SCOPE CREEP: Where did work expand beyond original quotes without matching price increases?\n4. PAYMENT BEHAVIOR: Were they prompt payers? Any disputes over invoices?\n5. VOLUME vs COMMITMENT: Did they promise volume that didn\'t materialize?\n6. COMPETITOR MENTIONS: Did they mention other suppliers? Use competitor pricing as leverage?\n7. PROFITABILITY ASSESSMENT: Based on the patterns, were they a profitable client or were we losing money?\n8. RE-ENGAGEMENT PRICING: What pricing strategy should we use to win them back without repeating past mistakes?'
                    },
                    {
                        id: 'winback',
                        name: 'Win-Back Strategy',
                        agent: 'general',
                        prompt: 'Based on everything in these emails AND your previous analysis passes (timeline, pressure tactics, profiles, financials), create a CONCRETE win-back strategy:\n\n1. ROOT CAUSE SUMMARY: In 3 sentences, why did we lose them?\n2. WHAT THEY VALUED: What did they actually appreciate about working with us?\n3. WHAT THEY HATED: What were their consistent pain points?\n4. COMPETITIVE POSITION: What would make them choose us over their current supplier?\n5. APPROACH PLAN:\n   - WHO to contact first (and why that person)\n   - WHEN (timing considerations based on their business cycle)\n   - HOW (email, call, in-person meeting?)\n   - WHAT to say (draft an opening message)\n   - WHAT TO OFFER (specific value proposition addressing their known pain points)\n6. RED LINES: What should we NOT agree to if they come back? What terms caused problems before?\n7. SUCCESS METRICS: How will we know the re-engagement is working?\n\nBe specific. Reference actual names, actual issues, actual quotes from the emails.'
                    }
                ]
            },

            // ---- RE-ENGAGEMENT EMAIL DRAFTS ----
            'regain_email': {
                name: 'Re-Engagement Emails',
                description: 'Draft re-engagement emails with persuasion techniques',
                passes: [
                    {
                        id: 'regain_analysis',
                        name: 'How to Regain Client',
                        agent: 'general',
                        prompt: 'Based on the complete email history, analyze WHY we lost this client and create a detailed re-engagement strategy:\n\n1. What exactly caused them to leave? (be specific, quote emails)\n2. What do they value most in a business partner?\n3. What unmet needs might their current supplier have?\n4. What timing signals suggest they might be open to reconnecting?\n5. What would make them give us a second chance?\n6. What should we absolutely avoid mentioning or doing?'
                    },
                    {
                        id: 'regain_email_direct',
                        name: 'Direct Re-engagement Email',
                        agent: 'email_composer',
                        prompt: 'Draft a professional re-engagement email to win back this client. Use these persuasion techniques:\n\n- RECIPROCITY: Offer something valuable upfront (insight, free consultation, industry report)\n- SOCIAL PROOF: Reference similar clients we\'ve helped recently\n- SCARCITY: Mention limited availability or exclusive offer\n- AUTHORITY: Subtly demonstrate our expertise growth since we last worked together\n- LIKING: Reference specific positive memories from our past collaboration\n- COMMITMENT: Start with a small ask (meeting, not a contract)\n\nThe email must feel natural, not salesy. Reference specific details from our history. Keep it under 200 words.'
                    },
                    {
                        id: 'regain_email_ai',
                        name: 'AI Value Proposition Email',
                        agent: 'email_composer',
                        prompt: 'Draft a re-engagement email specifically focused on how AI can benefit THIS client\'s company. Based on their industry and business:\n\n1. Research what their company does (from email context) and identify 3 specific AI use cases\n2. Explain how AI could solve problems they mentioned in emails or improve their operations\n3. Position us as the bridge between their business and AI transformation\n4. Include a concrete example or mini case study relevant to their industry\n5. Offer a free AI readiness assessment or demo\n\nMake it compelling, specific to THEIR company, not generic. Use the Cialdini persuasion principles subtly.'
                    },
                    {
                        id: 'indirect_steps',
                        name: 'Indirect Re-engagement Plan',
                        agent: 'general',
                        prompt: 'Create a 2-3 step INDIRECT re-engagement plan. Instead of contacting them directly, propose indirect touchpoints:\n\n1. STEP 1: Social/professional interaction (LinkedIn engagement, industry event, mutual connection intro, comment on their company news)\n2. STEP 2: Value-first contact (share a relevant article, invite to a webinar, send an industry report that benefits them)\n3. STEP 3: Warm re-engagement (after steps 1-2 create familiarity, make the direct ask)\n\nFor each step: specify WHAT to do, WHEN, through which CHANNEL, and WHAT to say. Use persuasion psychology: mere exposure effect, Ben Franklin effect, door-in-the-face, foot-in-the-door techniques.'
                    },
                    {
                        id: 'persuasion_toolkit',
                        name: 'Persuasion Techniques Toolkit',
                        agent: 'general',
                        prompt: 'Based on all email history and the client\'s psychological profile, create a persuasion toolkit:\n\n1. LOSS AVERSION: What are they losing by NOT working with us? Frame it.\n2. ANCHORING: What high-value anchor should we set before making our actual offer?\n3. CONTRAST PRINCIPLE: How to position our offer vs their current situation\n4. STORYTELLING: Craft a compelling narrative about a similar client\'s transformation\n5. OBJECTION HANDLING: List their likely objections and pre-written responses\n6. URGENCY TRIGGERS: What legitimate urgency factors can we introduce?\n7. NEGOTIATION PLAYBOOK: If they engage, what\'s our opening position, walkaway point, and BATNA?'
                    }
                ]
            },

            // ---- QUOTE OPTIMIZATION ----
            'quote_optimize': {
                name: 'Quote Optimization',
                description: 'Maximize quote value for current client discussions',
                passes: [
                    {
                        id: 'quote_history',
                        name: 'Quote & Pricing History',
                        agent: 'quote_analyst',
                        prompt: 'Analyze ALL pricing/quoting history in these emails:\n\n1. Create a TABLE of every quote, price, amount, date, and what it was for\n2. Track how prices changed over time — did we increase, decrease, or stay flat?\n3. What discounts did we give and why? Were they justified?\n4. How did the client react to each price point? (accepted quickly = too low, pushed back hard = near their limit)\n5. What\'s the client\'s apparent budget range based on their reactions?\n6. Are there patterns in WHEN they accept quotes (end of quarter, start of year, etc.)?'
                    },
                    {
                        id: 'client_budget',
                        name: 'Client Budget & Willingness',
                        agent: 'contact_profiler',
                        prompt: 'Build a psychological pricing profile for this client:\n\n1. What\'s their budget authority? Who approves what amounts?\n2. Are they price-sensitive or value-sensitive? Evidence from emails.\n3. Do they comparison shop? Have they mentioned competitors or alternative quotes?\n4. What non-price factors influence their decision (speed, quality, relationship, support)?\n5. What\'s their pain threshold — at what price point do they push back vs walk away?\n6. Do they negotiate every time or accept fair prices? What\'s their negotiation style?\n7. WILLINGNESS TO PAY: Based on all evidence, what\'s the maximum they would pay for our typical service?'
                    },
                    {
                        id: 'value_framing',
                        name: 'Value Framing Strategy',
                        agent: 'general',
                        prompt: 'Create a value framing strategy to maximize what we can charge:\n\n1. REFRAME FROM COST TO INVESTMENT: How to position our price as ROI, not expense\n2. UNBUNDLING: Can we break our offering into components to increase perceived value?\n3. TIERED OPTIONS: Design 3 pricing tiers (Good/Better/Best) with the middle one being our target\n4. COMPARISON ANCHORING: What expensive alternatives exist that make our price seem reasonable?\n5. VALUE QUANTIFICATION: Calculate the actual dollar value we deliver (time saved, revenue generated, problems avoided)\n6. RISK REVERSAL: What guarantees or pilot offers reduce their perceived risk?'
                    },
                    {
                        id: 'anchoring',
                        name: 'Anchoring & Negotiation Tactics',
                        agent: 'general',
                        prompt: 'Design a negotiation playbook for the current discussion:\n\n1. OPENING ANCHOR: What price should we start with? (typically 15-30% above target)\n2. JUSTIFICATION: How to justify the anchor with value-based reasoning\n3. CONCESSION STRATEGY: Plan 3 concessions we can make (each smaller than the last) — what to give and what to get in return\n4. NIBBLING: Small add-ons we can include that cost us little but add perceived value\n5. DEADLINE STRATEGY: How to create legitimate urgency without being pushy\n6. WALK-AWAY POINT: Below what price is this project not worth doing?\n7. BATNA: What\'s our best alternative if this deal doesn\'t happen?\n8. IF THEY WANT TO NEGOTIATE: Script for handling "can you do better on price?" with reciprocity'
                    },
                    {
                        id: 'quote_draft',
                        name: 'Optimal Quote Recommendation',
                        agent: 'quote_analyst',
                        prompt: 'Based on all previous analysis, recommend the optimal quote:\n\n1. RECOMMENDED PRICE: Exact amount with justification\n2. FLOOR PRICE: Minimum acceptable amount\n3. CEILING PRICE: Maximum we could reasonably charge\n4. PRESENTATION FORMAT: How to structure the quote document for maximum impact\n5. WHAT TO INCLUDE: Line items, value descriptions, terms that favor us\n6. WHAT TO EXCLUDE: Items to hold back for negotiation leverage\n7. TIMING: When to send the quote for best acceptance probability\n8. FOLLOW-UP SCRIPT: What to say 3 days after sending if no response\n9. MULTI-ROUND PLAN: If they push back, what\'s the next version of the quote?'
                    }
                ]
            },

            // ---- FULL RELATIONSHIP ANALYSIS ----
            'relationship': {
                name: 'Full Relationship Analysis',
                description: 'Comprehensive relationship health check',
                passes: [
                    {
                        id: 'timeline',
                        name: 'Business Relationship Timeline',
                        agent: 'general',
                        prompt: 'Analyze the COMPLETE email history chronologically. Build a detailed timeline of the business relationship:\n\n1. KEY MILESTONES: When did the relationship start? What were the major projects/deals? When did things start going wrong? When did we lose them?\n2. TURNING POINTS: Identify the exact moments where the relationship shifted negatively. Quote specific emails.\n3. OUR MISTAKES: What did we do wrong? Late deliveries, missed expectations, poor communication, pricing issues? Be brutally honest.\n4. THEIR SATISFACTION CURVE: Rate their satisfaction (1-10) at each major point in the timeline.\n5. UNRESOLVED ISSUES: What was never properly addressed or closed?\n6. LAST INTERACTION: What was the tone and content of our last exchange? Did we leave the door open?'
                    },
                    {
                        id: 'profiles',
                        name: 'Psychological Profiles',
                        agent: 'contact_profiler',
                        prompt: 'Build detailed psychological and business profiles for EACH person from the other party in these emails. For each person provide:\n\n1. NAME & ROLE (infer from email signatures and context)\n2. COMMUNICATION STYLE: Formal/casual, direct/indirect, emotional/analytical\n3. DECISION-MAKING: Do they decide alone or need approval? Fast or slow? Risk-averse?\n4. WHAT MOTIVATES THEM: Price? Quality? Relationships? Status? Control?\n5. HOW THEY HANDLE CONFLICT: Confrontational, avoidant, diplomatic, passive-aggressive?\n6. THEIR INFLUENCE: Who has real power vs who is just executing?\n7. THEIR ATTITUDE TOWARD US: Positive, neutral, negative? Did it change over time?\n8. APPROACH STRATEGY: How should we approach THIS specific person to rebuild the relationship?\n\nPay special attention to the CEO — what drives them, what frustrates them, what would win them back?'
                    },
                    {
                        id: 'financial',
                        name: 'Financial & Business Patterns',
                        agent: 'quote_analyst',
                        prompt: 'Analyze the complete financial and business history:\n\n1. ALL PRICES QUOTED: Every amount, every project, every change order — create a table\n2. PRICING TRENDS: Did our prices go up/down? Did they push for discounts? How much did we concede?\n3. SCOPE CREEP: Where did work expand beyond original quotes without matching price increases?\n4. PAYMENT BEHAVIOR: Were they prompt payers? Any disputes over invoices?\n5. VOLUME vs COMMITMENT: Did they promise volume that didn\'t materialize?\n6. COMPETITOR MENTIONS: Did they mention other suppliers? Use competitor pricing as leverage?\n7. PROFITABILITY ASSESSMENT: Based on the patterns, were they a profitable client or were we losing money?\n8. RE-ENGAGEMENT PRICING: What pricing strategy should we use to win them back without repeating past mistakes?'
                    },
                    {
                        id: 'pressure',
                        name: 'Pressure & Manipulation Detection',
                        agent: 'deception_detector',
                        prompt: 'Analyze ALL emails from the other party\'s team members for:\n\n1. PRESSURE TACTICS: Where did they push unreasonable deadlines, scope changes, or price reductions? Quote specific examples.\n2. BROKEN PROMISES from their side: Did they commit to volumes, timelines, payments that didn\'t materialize?\n3. DOUBLE STANDARDS: Did they hold us to standards they didn\'t meet themselves?\n4. ESCALATION PATTERNS: When and why did they escalate to the CEO? Was it justified or a power play?\n5. BLAME SHIFTING: Did they blame us for problems that were partially/fully their responsibility?\n6. GOOD FAITH SIGNALS: To be fair — where were they genuinely reasonable or helpful?\n\nRate each team member\'s negotiation tactics: FAIR / AGGRESSIVE / MANIPULATIVE with evidence.'
                    }
                ]
            }
        };