Now fix the `submitToAI()` function to use `thread_for_ai`, add content truncation, and better error handling. Let me find the relevant section:


2243:                        var threadData = await fetch('api.php?action=thread&thread_id=' + tid);


  2230→                }
  2231→
  2232→                // Add context if provided
  2233→                if (context) {
  2234→                    fullContent += '\n\nADDITIONAL CONTEXT:\n' + context;
  2235→                }
  2236→
  2237→                // Fetch additional thread content (checkboxes + context builder threads)
  2238→                if (allAdditionalThreads.length > 0) {
  2239→                    document.getElementById('loading-message').textContent = 'Loading additional threads...';
  2240→
  2241→                    for (var i = 0; i < allAdditionalThreads.length; i++) {
  2242→                        var tid = allAdditionalThreads[i];
  2243→                        var threadData = await fetch('api.php?action=thread&thread_id=' + tid);
  2244→                        var thread = await threadData.json();
  2245→
  2246→                        if (thread.emails && thread.emails.length > 0) {
  2247→                            fullContent += '\n\n--- ADDITIONAL THREAD ' + (i + 1) + ' OF ' + allAdditionalThreads.length + ' ---\n';
  2248→                            fullContent += 'Subject: ' + (thread.emails[0].subject || '(No Subject)') + '\n\n';
  2249→                            fullContent += processAdditionalThreadContent(thread.emails, contentMode);
  2250→                        }
  2251→                    }
  2252→                }
  2253→
  2254→                var finalTokens = Math.ceil(fullContent.length / 3.5);
  2255→
  2256→                // Log to debug file BEFORE sending
  2257→                logAiDebug({
  2258→                    type: 'request',
  2259→                    thread_id: currentThreadId,
  2260→                    agent: selectedAgent,
  2261→                    providers: selectedProvidersList,
  2262→                    models: modelsMap,
  2263→                    content_length: fullContent.length,
  2264→                    estimated_tokens: finalTokens,
  2265→                    question: actualQuestion,
  2266→                    context_threads: allAdditionalThreads,
  2267→                    full_content: fullContent
  2268→                });
  2269→
  2270→                // Console log
  2271→                console.log('=== AI REQUEST LOG ===');
  2272→                console.log('Agent:', selectedAgent);
  2273→                console.log('Providers:', selectedProvidersList);
  2274→                console.log('Models:', modelsMap);
  2275→                console.log('Content Mode:', contentMode);
  2276→                console.log('Context Threads:', allAdditionalThreads.length);
  2277→                console.log('Conversation History:', conversationHistory.length);
  2278→                console.log('Content Length:', fullContent.length, 'chars');
  2279→                console.log('Estimated Tokens:', finalTokens);
  2280→                console.log('======================');
  2281→
  2282→                document.getElementById('loading-message').textContent = 'Analyzing with ' + selectedProvidersList.length + ' AI provider(s)...';
  2283→
  2284→                // Build request body with all selected providers and their models
  2285→                var requestBody = {
  2286→                    user_content: fullContent,
  2287→                    providers: selectedProvidersList
  2288→                };
  2289→

                }

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

                // Fetch additional thread content (checkboxes + context builder threads)
                if (allAdditionalThreads.length > 0) {
                    document.getElementById('loading-message').textContent = 'Loading additional threads...';

                    for (var i = 0; i < allAdditionalThreads.length; i++) {
                        var tid = allAdditionalThreads[i];
                        var threadData = await fetch('api.php?action=thread&thread_id=' + tid);
                        var thread = await threadData.json();

                        if (thread.emails && thread.emails.length > 0) {
                            fullContent += '\n\n--- ADDITIONAL THREAD ' + (i + 1) + ' OF ' + allAdditionalThreads.length + ' ---\n';
                            fullContent += 'Subject: ' + (thread.emails[0].subject || '(No Subject)') + '\n\n';
                            fullContent += processAdditionalThreadContent(thread.emails, contentMode);
                        }
                    }
                }

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

                // Log to debug file BEFORE sending
                logAiDebug({
                    type: 'request',
                    thread_id: currentThreadId,
                    agent: selectedAgent,
                    providers: selectedProvidersList,
                    models: modelsMap,
                    content_length: fullContent.length,
                    estimated_tokens: finalTokens,
                    question: actualQuestion,
                    context_threads: allAdditionalThreads,
                    full_content: fullContent
                });

                // Console log
                console.log('=== AI REQUEST LOG ===');
                console.log('Agent:', selectedAgent);
                console.log('Providers:', selectedProvidersList);
                console.log('Models:', modelsMap);
                console.log('Content Mode:', contentMode);
                console.log('Context Threads:', allAdditionalThreads.length);
                console.log('Conversation History:', conversationHistory.length);
                console.log('Content Length:', fullContent.length, 'chars');
                console.log('Estimated Tokens:', finalTokens);
                console.log('======================');

                document.getElementById('loading-message').textContent = 'Analyzing with ' + selectedProvidersList.length + ' AI provider(s)...';

                // Build request body with all selected providers and their models
                var requestBody = {
                    user_content: fullContent,
                    providers: selectedProvidersList
                };


Now replace the thread fetch + add content truncation and error handling:


Edit

                // Fetch additional thread content (checkboxes + context builder threads)
                if (allAdditionalThreads.length > 0) {
                    document.getElementById('loading-message').textContent = 'Loading additional threads...';

                    for (var i = 0; i < allAdditionalThreads.length; i++) {
                        var tid = allAdditionalThreads[i];
                        var threadData = await fetch('api.php?action=thread&thread_id=' + tid);
                        var thread = await threadData.json();

                        if (thread.emails && thread.emails.length > 0) {
                            fullContent += '\n\n--- ADDITIONAL THREAD ' + (i + 1) + ' OF ' + allAdditionalThreads.length + ' ---\n';
                            fullContent += 'Subject: ' + (thread.emails[0].subject || '(No Subject)') + '\n\n';
                            fullContent += processAdditionalThreadContent(thread.emails, contentMode);
                        }
                    }
                }

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

                // Log to debug file BEFORE sending
                logAiDebug({
                    type: 'request',
                    thread_id: currentThreadId,
                    agent: selectedAgent,
                    providers: selectedProvidersList,
                    models: modelsMap,
                    content_length: fullContent.length,
                    estimated_tokens: finalTokens,
                    question: actualQuestion,
                    context_threads: allAdditionalThreads,
                    full_content: fullContent
                });

                // Fetch additional thread content (checkboxes + context builder threads)
                // Uses thread_for_ai endpoint (lightweight, stripped bodies, no analysis)
                if (allAdditionalThreads.length > 0) {
                    document.getElementById('loading-message').textContent = 'Loading additional threads (0/' + allAdditionalThreads.length + ')...';

                    for (var i = 0; i < allAdditionalThreads.length; i++) {
                        var tid = allAdditionalThreads[i];
                        document.getElementById('loading-message').textContent = 'Loading thread ' + (i + 1) + '/' + allAdditionalThreads.length + '...';
                        try {
                            var threadResp = await fetch('api.php?action=thread_for_ai&thread_id=' + tid);
                            if (!threadResp.ok) {
                                console.warn('Failed to fetch thread ' + tid + ': HTTP ' + threadResp.status);
                                fullContent += '\n\n--- THREAD ' + (i + 1) + ': FAILED TO LOAD (HTTP ' + threadResp.status + ') ---\n';
                                continue;
                            }
                            var thread = await threadResp.json();

                            if (thread.emails && thread.emails.length > 0) {
                                fullContent += '\n\n--- ADDITIONAL THREAD ' + (i + 1) + ' OF ' + allAdditionalThreads.length + ' ---\n';
                                fullContent += 'Subject: ' + (thread.emails[0].subject || '(No Subject)') + '\n\n';
                                // Bodies already stripped by thread_for_ai endpoint
                                fullContent += processAdditionalThreadContent(thread.emails, 'full');
                            }
                        } catch (fetchErr) {
                            console.warn('Error fetching thread ' + tid + ':', fetchErr);
                            fullContent += '\n\n--- THREAD ' + (i + 1) + ': FETCH ERROR ---\n';
                        }
                    }
                }

                // Enforce content budget: truncate to fit smallest model limit
                var maxChars = Math.floor(modelLimit * 3.5 * 0.85); // 85% of model limit in chars
                var wasTruncated = false;
                if (fullContent.length > maxChars) {
                    wasTruncated = true;
                    fullContent = fullContent.substring(0, maxChars) + '\n\n...(Content truncated to fit model context limit of ' + modelLimit.toLocaleString() + ' tokens)';
                }

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

                // Log to debug file BEFORE sending
                logAiDebug({
                    type: 'request',
                    thread_id: currentThreadId,
                    agent: selectedAgent,
                    providers: selectedProvidersList,
                    models: modelsMap,
                    content_length: fullContent.length,
                    estimated_tokens: finalTokens,
                    question: actualQuestion,
                    context_threads: allAdditionalThreads,
                    truncated: wasTruncated,
                    full_content: fullContent
                });