TodoWrite

Add Two-Round AI checkbox and response selection UI

Implement Round 2 auto-summary logic in submitToAI

Add manual response selection + follow-up feature

Add timeout handling for slow providers

Test and verify PHP syntax


Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable

Add Two-Round AI checkbox and response selection UI

Implement Round 2 auto-summary logic in submitToAI

Add manual response selection + follow-up feature

Add timeout handling for slow providers

Test and verify PHP syntax

Add timeout handling for slow providers

Test and verify PHP syntax


Now I need to modify `displayAIResponse()` to add checkboxes for response selection, and modify `submitToAI()` to use timeout + trigger Round 2. Let me find and replace `displayAIResponse`:


2958:        function displayAIResponse(data) {


2958→        function displayAIResponse(data) {
  2959→            const container = document.getElementById('ai-response-container');
  2960→            const tabsContainer = document.getElementById('response-tabs');
  2961→            const contentContainer = document.getElementById('ai-responses-content');
  2962→
  2963→            container.style.display = 'block';
  2964→            tabsContainer.innerHTML = '';
  2965→            contentContainer.innerHTML = '';
  2966→
  2967→            let tabIndex = 0;
  2968→            for (const [key, response] of Object.entries(data.responses)) {
  2969→                const providerName = key.replace('_response', '');
  2970→                const providerConfig = providers[providerName] || { name: providerName };
  2971→
  2972→                // Create tab
  2973→                const tab = document.createElement('button');
  2974→                tab.className = 'response-tab' + (tabIndex === 0 ? ' active' : '');
  2975→                tab.textContent = providerConfig.name;
  2976→                tab.onclick = () => switchResponseTab(tabIndex);
  2977→                tab.dataset.index = tabIndex;
  2978→                tabsContainer.appendChild(tab);
  2979→
  2980→                // Create content
  2981→                const content = document.createElement('div');
  2982→                content.className = 'response-content' + (tabIndex === 0 ? ' active' : '');
  2983→                content.id = 'response-tab-' + tabIndex;
  2984→
  2985→                if (response.success) {
  2986→                    content.innerHTML = `
  2987→

  2988→

  2989→                                ${providerConfig.name}
  2990→
  2991→                                    Model: ${response.model || 'Unknown'} |
  2992→                                    Time: ${response.request_time?.toFixed(2) || '?'}s |
  2993→                                    Cost: $${response.cost?.toFixed(6) || '0'}
  2994→
  2995→

  2996→
${escapeHtml(response.response)}

  2997→

  2998→                    `;
  2999→                } else {
  3000→                    content.innerHTML = `
  3001→

  3002→                            Error:
  3003→
${escapeHtml(response.error || 'Unknown error')}

  3004→

  3005→                    `;
  3006→                }
  3007→
  3008→                contentContainer.appendChild(content);
  3009→                tabIndex++;

function displayAIResponse(data) {
            const container = document.getElementById('ai-response-container');
            const tabsContainer = document.getElementById('response-tabs');
            const contentContainer = document.getElementById('ai-responses-content');

            container.style.display = 'block';
            tabsContainer.innerHTML = '';
            contentContainer.innerHTML = '';

            let tabIndex = 0;
            for (const [key, response] of Object.entries(data.responses)) {
                const providerName = key.replace('_response', '');
                const providerConfig = providers[providerName] || { name: providerName };

                // Create tab
                const tab = document.createElement('button');
                tab.className = 'response-tab' + (tabIndex === 0 ? ' active' : '');
                tab.textContent = providerConfig.name;
                tab.onclick = () => switchResponseTab(tabIndex);
                tab.dataset.index = tabIndex;
                tabsContainer.appendChild(tab);

                // Create content
                const content = document.createElement('div');
                content.className = 'response-content' + (tabIndex === 0 ? ' active' : '');
                content.id = 'response-tab-' + tabIndex;

                if (response.success) {
                    content.innerHTML = `

                                ${providerConfig.name}

                                    Model: ${response.model || 'Unknown'} |
                                    Time: ${response.request_time?.toFixed(2) || '?'}s |
                                    Cost: $${response.cost?.toFixed(6) || '0'}

${escapeHtml(response.response)}

                    `;
                } else {
                    content.innerHTML = `

                            Error:

${escapeHtml(response.error || 'Unknown error')}

                    `;
                }

                contentContainer.appendChild(content);
                tabIndex++;


  3008→                contentContainer.appendChild(content);
  3009→                tabIndex++;
  3010→            }
  3011→
  3012→            // Scroll to response
  3013→            container.scrollIntoView({ behavior: 'smooth' });
  3014→        }
  3015→
  3016→        // Switch response tabs - scoped to response container only
  3017→        function switchResponseTab(index) {

                contentContainer.appendChild(content);
                tabIndex++;
            }

            // Scroll to response
            container.scrollIntoView({ behavior: 'smooth' });
        }

        // Switch response tabs - scoped to response container only
        function switchResponseTab(index) {


Replace `displayAIResponse` to add selection checkboxes:


Edit

function displayAIResponse(data) {
            const container = document.getElementById('ai-response-container');
            const tabsContainer = document.getElementById('response-tabs');
            const contentContainer = document.getElementById('ai-responses-content');

            container.style.display = 'block';
            tabsContainer.innerHTML = '';
            contentContainer.innerHTML = '';

            let tabIndex = 0;
            for (const [key, response] of Object.entries(data.responses)) {
                const providerName = key.replace('_response', '');
                const providerConfig = providers[providerName] || { name: providerName };

                // Create tab
                const tab = document.createElement('button');
                tab.className = 'response-tab' + (tabIndex === 0 ? ' active' : '');
                tab.textContent = providerConfig.name;
                tab.onclick = () => switchResponseTab(tabIndex);
                tab.dataset.index = tabIndex;
                tabsContainer.appendChild(tab);

                // Create content
                const content = document.createElement('div');
                content.className = 'response-content' + (tabIndex === 0 ? ' active' : '');
                content.id = 'response-tab-' + tabIndex;

                if (response.success) {
                    content.innerHTML = `

                                ${providerConfig.name}

                                    Model: ${response.model || 'Unknown'} |
                                    Time: ${response.request_time?.toFixed(2) || '?'}s |
                                    Cost: $${response.cost?.toFixed(6) || '0'}

${escapeHtml(response.response)}

                    `;
                } else {
                    content.innerHTML = `

                            Error:

${escapeHtml(response.error || 'Unknown error')}

                    `;
                }

                contentContainer.appendChild(content);
                tabIndex++;
            }

            // Scroll to response
            container.scrollIntoView({ behavior: 'smooth' });
        }

function displayAIResponse(data, roundLabel) {
            var container = document.getElementById('ai-response-container');
            var tabsContainer = document.getElementById('response-tabs');
            var contentContainer = document.getElementById('ai-responses-content');
            var badge = document.getElementById('response-round-badge');

            container.style.display = 'block';
            tabsContainer.innerHTML = '';
            contentContainer.innerHTML = '';

            // Update badge
            if (badge) {
                badge.textContent = roundLabel || 'Round 1';
                badge.className = 'round-badge round-1';
            }

            // Hide Round 2 container (fresh start)
            document.getElementById('ai-response-round2-container').style.display = 'none';

            // Store responses for follow-up
            lastRound1Responses = {};

            var tabIndex = 0;
            var successCount = 0;
            var failCount = 0;

            for (var key in data.responses) {
                var response = data.responses[key];
                var providerName = key.replace('_response', '');
                var providerConfig = providers[providerName] || { name: providerName };

                // Store for Round 2 / follow-up
                lastRound1Responses[providerName] = response;

                // Create tab
                var tab = document.createElement('button');
                tab.className = 'response-tab' + (tabIndex === 0 ? ' active' : '');
                tab.textContent = providerConfig.name + (response.success ? '' : ' (fail)');
                tab.dataset.index = tabIndex;
                (function(idx) {
                    tab.onclick = function() { switchResponseTab(idx); };
                })(tabIndex);
                tabsContainer.appendChild(tab);

                // Create content with selection checkbox
                var contentDiv = document.createElement('div');
                contentDiv.className = 'response-content' + (tabIndex === 0 ? ' active' : '');
                contentDiv.id = 'response-tab-' + tabIndex;

                if (response.success) {
                    successCount++;
                    var cbId = 'resp-cb-' + providerName;
                    contentDiv.innerHTML = '
' +
                        '<input type="checkbox" class="response-select-cb" id="' + cbId + '" checked ' +
                        'data-provider="' + escapeHtml(providerName) + '" ' +
                        'data-model="' + escapeHtml(response.model || '') + '" ' +
                        'data-response-text="' + escapeHtml(response.response || '').replace(/"/g, '"') + '">' +
                        'Include in follow-up' +
                        '
' +
                        '
' +
                        '
' +
                        '' + escapeHtml(providerConfig.name) + '' +
                        '' +
                        'Model: ' + escapeHtml(response.model || 'Unknown') + ' | ' +
                        'Time: ' + (response.request_time ? response.request_time.toFixed(2) : '?') + 's | ' +
                        'Cost: $' + (response.cost ? response.cost.toFixed(6) : '0') +
                        '
' +
                        '
' + escapeHtml(response.response) + '
' +
                        '
';
                } else {
                    failCount++;
                    contentDiv.innerHTML = '
' +
                        'Error (' + escapeHtml(providerConfig.name) + '):' +
                        '
' + escapeHtml(response.error || 'Unknown error / timeout') + '

';
                }

                contentContainer.appendChild(contentDiv);
                tabIndex++;
            }

            // Show the follow-up bar
            var selectBar = document.getElementById('response-select-bar');
            if (selectBar && successCount > 0) {
                selectBar.style.display = 'flex';
            }

            // Add summary line if mixed results
            if (failCount > 0 && successCount > 0) {
                var summaryDiv = document.createElement('div');
                summaryDiv.className = 'provider-timeout';
                summaryDiv.style.marginTop = '10px';
                summaryDiv.innerHTML = successCount + ' provider(s) responded, ' + failCount + ' failed/timed out. Successful responses are shown above.';
                contentContainer.appendChild(summaryDiv);
            }

            container.scrollIntoView({ behavior: 'smooth' });
        }