Einfacher Multi-AI Chat (GPT-5 Nano & Claude)

GPT-5 Nano

Claude

loseCompareModal() { document.getElementById('compareModal').style.display = 'none'; } function validateSelection(type) { const listId = type === 'select' ? '#aiList' : '#compareList'; const warningId = type === 'select' ? '#select-warning' : '#compare-warning'; const checked = document.querySelectorAll(listId + ' input:checked'); const max = type === 'select' ? 5 : 1; if (checked.length > max) { document.querySelector(warningId).style.display = 'block'; while (checked.length > max) { checked[checked.length - 1].checked = false; } } else { document.querySelector(warningId).style.display = 'none'; } } function saveSelection() { const checkedBoxes = document.querySelectorAll('#aiList input:checked'); selectedAIs = Array.from(checkedBoxes).map(cb => { const label = cb.nextElementSibling.textContent; const name = label.replace(/ \(\w+\)/, '').trim(); return { name, model: cb.value }; }).slice(0, 5); closeSelectModal(); alert(`Auswahl gespeichert: ${selectedAIs.length} Modelle aktiv.`); } // Streaming-Funktion mit Abort und Typing async function streamAIResponse(ai, index, abortController) { const container = document.getElementById(`content-${index}`); const stopBtn = document.getElementById(`stop-${index}`); let fullResult = ''; let isAborted = false; // Typing-Indikator anzeigen container.innerHTML = 'tippt'; stopBtn.style.display = 'inline-block'; try { const stream = await puter.ai.chat(currentQuestion, { model: ai.model, stream: true, signal: abortController.signal }); for await (const chunk of stream) { if (abortController.signal.aborted) { isAborted = true; break; } fullResult += chunk; container.innerHTML = fullResult.replace(/\n/g, '
'); } if (!isAborted) { // Typing entfernen stopBtn.style.display = 'none'; } else { container.innerHTML = 'Abgebrochen'; fullResult = 'Abgebrochen'; } } catch (error) { if (error.name === 'AbortError') { container.innerHTML = 'Abgebrochen'; fullResult = 'Abgebrochen'; } else { container.innerHTML = `

Fehler: ${error.message}

`; fullResult = `Fehler: ${error.message}`; } stopBtn.style.display = 'none'; } return fullResult; } // Stop-Funktion pro Karte function stopStream(index) { const controller = abortControllers[index]; if (controller) { controller.abort(); } } // Hauptfunktion: Parallele Streams async function askAIs() { currentQuestion = document.getElementById('question').value.trim(); if (!currentQuestion) return alert('Bitte eine Frage eingeben!'); if (selectedAIs.length === 0) return alert('Bitte mindestens ein AI-Modell auswählen!'); const resultsDiv = document.getElementById('results'); resultsDiv.innerHTML = ''; currentResponses = []; abortControllers = []; // Reset const promises = selectedAIs.map((ai, index) => { const controller = new AbortController(); abortControllers.push(controller); const card = document.createElement('div'); card.className = 'ai-card'; card.id = `card-${index}`; card.innerHTML = `

${ai.name}

`; resultsDiv.appendChild(card); return streamAIResponse(ai, index, controller).then(result => { currentResponses.push({ ...ai, result }); }); }); await Promise.all(promises.filter(p => p)); // Ignoriere abgebrochene // Buttons anzeigen document.getElementById('compare-section').style.display = 'block'; } // Export als Markdown (inkl. Frage, Antworten, Vergleich) function exportResponses() { if (currentResponses.length === 0) return alert('Keine Antworten zum Exportieren!');