import { api } from "../lib/api.js"; import { on } from "../lib/bus.js"; class RunTimeline extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); this.chatId = null; this.items = []; this.selectedDebug = null; this.shadowRoot.innerHTML = `
Conversación
Seleccioná una conversación.
Debug (click en burbuja roja para ver detalles)
`; } connectedCallback() { this.shadowRoot.getElementById("refresh").onclick = () => this.loadMessages(); this._unsubSel = on("ui:selectedChat", async ({ chat_id }) => { this.chatId = chat_id; await this.loadMessages(); }); this._unsubRun = on("run:created", (run) => { if (this.chatId && run.chat_id === this.chatId) { // nuevo run => refrescar mensajes para ver los bubbles actualizados this.loadMessages(); } }); } disconnectedCallback() { this._unsubSel?.(); this._unsubRun?.(); } async loadMessages() { this.shadowRoot.getElementById("chat").textContent = this.chatId || "—"; this.shadowRoot.getElementById("meta").textContent = "Cargando…"; this.shadowRoot.getElementById("count").textContent = ""; if (!this.chatId) { this.shadowRoot.getElementById("meta").textContent = "Seleccioná una conversación."; this.shadowRoot.getElementById("log").innerHTML = ""; this.shadowRoot.getElementById("debug").textContent = "—"; return; } const data = await api.messages({ chat_id: this.chatId, limit: 200 }); this.items = data.items || []; this.render(); } isErrorMsg(m) { const txt = String(m?.text || ""); return Boolean(m?.payload?.error) || txt.startsWith("[ERROR]") || txt.toLowerCase().includes("internal_error"); } render() { const meta = this.shadowRoot.getElementById("meta"); const count = this.shadowRoot.getElementById("count"); const log = this.shadowRoot.getElementById("log"); const dbg = this.shadowRoot.getElementById("debug"); meta.textContent = `Mostrando historial (últimos ${this.items.length}).`; count.textContent = this.items.length ? `${this.items.length} msgs` : ""; log.innerHTML = ""; for (const m of this.items) { const who = m.direction === "in" ? "user" : "bot"; const isErr = this.isErrorMsg(m); const bubble = document.createElement("div"); bubble.className = `bubble ${isErr ? "err" : who}`; bubble.textContent = m.text || (isErr ? "Error" : "—"); const metaEl = document.createElement("span"); metaEl.className = "meta"; metaEl.textContent = `${new Date(m.ts).toLocaleString()} • ${m.provider} • ${m.message_id}`; bubble.appendChild(metaEl); if (isErr) { bubble.title = "Click para ver detalles (JSON)"; bubble.onclick = () => { dbg.textContent = JSON.stringify(m, null, 2); }; } log.appendChild(bubble); } // auto-scroll log.scrollTop = log.scrollHeight; if (!this.items.length) dbg.textContent = "—"; } } customElements.define("run-timeline", RunTimeline);