"use strict"; // La barra lateral: una caja de texto y lo que contestó el modelo local. // // `?q=…` abre el panel con la pregunta ya hecha. Es la puerta por la que entran las // preguntas que NO se tipean acá (y la que usa el guardián); no es superficie de // prueba: sin ella, «preguntarle a la IA sobre esto» tendría que reescribir la // pregunta a mano. function agregar(clase, texto) { const d = document.createElement("div"); d.className = "turno " + clase; d.textContent = texto; document.getElementById("hilo").appendChild(d); d.scrollIntoView({ block: "end" }); return d; } async function preguntar(texto) { if (!texto.trim()) return; agregar("yo", texto); const esperando = agregar("", "pensando…"); const boton = document.getElementById("enviar"); boton.disabled = true; let r; try { r = await browser.runtime.sendMessage({ tipo: "preguntar", texto }); } catch (e) { r = { ok: false, error: String(e) }; } boton.disabled = false; // La causa se MUESTRA. «No pude contestar» a secas dejaría al usuario sin saber // si falta el modelo, si el motor no está en la imagen o si se cayó el host. if (!r || !r.ok) { esperando.className = "turno error"; esperando.textContent = (r && r.error) || "el host no contestó"; return; } esperando.textContent = r.answer; } // Las páginas ya leídas (§6.3): la misma caja, otra pregunta. No se mezcla con la del // modelo a propósito — una INVENTA texto y la otra devuelve lo que vos leíste, y presentarlas // juntas haría imposible saber cuál de las dos contestó. async function buscarEnMisPaginas(texto) { if (!texto.trim()) return; agregar("yo", texto); const esperando = agregar("", "buscando en lo que leíste…"); let r; try { r = await browser.runtime.sendMessage({ tipo: "archivo", texto }); } catch (e) { r = { ok: false, error: String(e) }; } if (!r || !r.ok) { esperando.className = "turno error"; esperando.textContent = (r && r.error) || "el host no contestó"; return; } const m = r.matches || []; if (!m.length) { esperando.textContent = `no encontré nada entre tus ${r.archived} páginas`; return; } // Se muestran EN ORDEN y sin porcentaje: el puntaje es un coseno y leerlo como // «85 % de acierto» sería inventarle un significado que no tiene. esperando.textContent = `de tus ${r.archived} páginas, en orden de parecido:`; for (const c of m.slice(0, 8)) { const d = document.createElement("div"); d.className = "fuente"; const a = document.createElement("a"); a.href = c.page.url; a.textContent = c.page.title || c.page.url; a.title = c.page.url; d.appendChild(a); esperando.appendChild(d); } } document.getElementById("forma").addEventListener("submit", (ev) => { ev.preventDefault(); const caja = document.getElementById("texto"); const texto = caja.value; caja.value = ""; preguntar(texto); }); document.getElementById("archivo").addEventListener("click", () => { const caja = document.getElementById("texto"); const texto = caja.value; caja.value = ""; buscarEnMisPaginas(texto); }); // `?q=` pregunta al modelo; `?p=` busca en las páginas. Las dos son la puerta por la que // entran las preguntas que no se tipean acá (y las que usan los guardianes). const params = new URLSearchParams(location.search); const q = params.get("q"); if (q) preguntar(q); const pag = params.get("p"); if (pag) buscarEnMisPaginas(pag);