Now add the `runDeepAnalysis()` function. I'll add it right before the `submitToAI` function:


3057:        // Submit to AI

3057:        // Submit to AI


  3054→            return content;
  3055→        }
  3056→
  3057→        // Submit to AI
  3058→        async function submitToAI() {

            return content;
        }

        // Submit to AI
        async function submitToAI() {


Edit

        // Submit to AI
        async function submitToAI() {

// ============================================
        // DEEP ANALYSIS — Automated 5-Pass Execution
        // ============================================
        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;
            }
        }

        // Submit to AI
        async function submitToAI() {