Rilascia PDF, DOCX, TXT, MD o immagini qui…
Elaborazione…

💬 Risposta RAG

Elaborazione…

📌 Fonti utilizzate

`; const blob = new Blob([html], {type: 'text/html;charset=utf-8'}); window.open(URL.createObjectURL(blob), '_blank'); }; /* ═══════════════════════════════════════ ASK DOC – Q&A su singolo documento ═══════════════════════════════════════ */ window.askDoc = async function(id) { const doc = docs.find(x => x.id === id); if (!doc) return; const q = window.prompt(`Fai una domanda su "${doc.name}":`); if (!q || !q.trim()) return; await ragQA(q.trim(), id); }; /* ═══════════════════════════════════════ DELETE – rimuove doc + tutti i chunk ═══════════════════════════════════════ */ window.deleteDoc = async function(id) { if (!confirm('Rimuovere il documento e tutti i suoi chunk dall\'archivio?')) return; await Promise.all([deleteDocDB(id), deleteChunksByDocId(id)]); await loadDocs(); }; /* ═══════════════════════════════════════ PULSANTI ═══════════════════════════════════════ */ function installButtons() { els.btnSearch.addEventListener('click', search); els.searchBox.addEventListener('keypress', e => { if (e.key === 'Enter') search(); }); els.btnShowAll.addEventListener('click', async () => { els.searchBox.value = ''; await loadDocs(); }); /* Chiudi modal Q&A */ els.qaClose.addEventListener('click', () => els.qaModal.classList.remove('active')); els.qaModal.addEventListener('click', e => { if (e.target === els.qaModal) els.qaModal.classList.remove('active'); }); /* Re-indicizzazione con chunking */ els.btnReindex.addEventListener('click', async () => { if (!confirm('Rigenerare tutti i chunk e gli embedding?\nI chunk esistenti verranno eliminati e ricreati con il provider attuale.')) return; docs = await getAllDocs(); for (let k = 0; k < docs.length; k++) { const d = docs[k]; showLoad(true, `[${k+1}/${docs.length}] Chunk: ${d.name}`, ''); await deleteChunksByDocId(d.id); const chunks = chunkText(d.text); for (let ci = 0; ci < chunks.length; ci++) { showLoad(true, `[${k+1}/${docs.length}] Embedding chunk ${ci+1}/${chunks.length}`, d.name ); const emb = await embedAPI(chunks[ci]); await addChunk({docId: d.id, chunkIndex: ci, text: chunks[ci], embedding: emb}); } /* aggiorna metadati del documento (inclusi modello testo e conteggio chunk) */ d.providerUsed = els.provider.value; d.textModel = getModel('text'); d.embedModel = getModel('embed'); d.indexedAt = new Date().toISOString(); d.chunkCount = chunks.length; await updateDoc(d); } showLoad(false); alert('Re-indicizzazione con chunking completata!'); await loadDocs(); }); /* Esportazione CSV arricchita */ els.btnExport.addEventListener('click', () => { const header = 'nome_file,tipo,byte,data,tags,riassunto_ai,provider,modello_testo,modello_embedding,indicizzato_il\n'; const rows = docs.map(d => { const f = [ d.name, d.type || '', d.size || 0, d.date ? new Date(d.date).toLocaleString('it-IT') : '', (d.tags || []).join(';'), (d.summary || '').replace(/\n/g,' '), d.providerUsed || '', d.textModel || '', d.embedModel || '', d.indexedAt ? new Date(d.indexedAt).toLocaleString('it-IT') : '', ]; return f.map(v => `"${String(v).replace(/"/g,'""')}"`).join(','); }).join('\n'); const blob = new Blob(['\uFEFF' + header + rows], {type: 'text/csv;charset=utf-8'}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = `cassetto_export_${Date.now()}.csv`; a.click(); }); /* Svuota archivio */ els.btnClearDB.addEventListener('click', async () => { if (!confirm('ATTENZIONE: eliminare tutti i documenti e tutti i chunk?')) return; await Promise.all([clearAllDocs(), clearAllChunks()]); docs = []; updateStats(); renderResults([]); }); } /* ═══════════════════════════════════════ WEB WORKER SETUP ═══════════════════════════════════════ */ function installWorker() { const check = setInterval(() => { if (!window.inBrowserWorker) return; clearInterval(check); window.inBrowserWorker.onmessage = ({data: {id, vec, status}}) => { if (status === 'download') setStatus('Browser: download modello…'); if (status === 'embedding') setStatus('Browser: calcolo embedding…'); const resolve = fallbackPending.get(id); if (resolve && vec) { fallbackPending.delete(id); resolve(vec); setStatus('🟢 In-browser pronto', '#2aa198'); } }; }, 100); } /* ═══════════════════════════════════════ HELPERS ═══════════════════════════════════════ */ function setStatus(msg, color = '#657b83') { els.connStatus.textContent = msg; els.connStatus.style.color = color; } function showLoad(on, msg = 'Elaborazione…', detail = '') { if (on) { els.loadingText.textContent = msg; els.loadingDetail.textContent = detail; els.loading.classList.add('active'); } else { els.loading.classList.remove('active'); } } function fmtSize(b) { if (!b) return '?'; if (b < 1024) return `${b} B`; if (b < 1048576) return `${(b/1024).toFixed(1)} KB`; return `${(b/1048576).toFixed(1)} MB`; } function fmtDate(d) { if (!d) return '?'; try { return new Date(d).toLocaleDateString('it-IT'); } catch(e) { return '?'; } }