mejoras en el modelo de clarificacion de productos

This commit is contained in:
Lucas Tettamanti
2026-01-17 06:31:49 -03:00
parent 63b9ecef61
commit 204403560e
24 changed files with 1940 additions and 873 deletions

View File

@@ -61,6 +61,8 @@ class ConversationInspector extends HTMLElement {
this.shadowRoot.getElementById("step").onclick = () => this.step();
this._unsubSel = on("ui:selectedChat", async ({ chat_id }) => {
// Si es el mismo chat, no recargar (para no borrar items optimistas)
if (this.chatId === chat_id) return;
this.chatId = chat_id;
await this.loadData();
});
@@ -87,6 +89,17 @@ class ConversationInspector extends HTMLElement {
const messageId = message?.message_id || null;
if (messageId) this.highlight(messageId);
});
// Listen for optimistic messages to add placeholder item
this._unsubOptimistic = on("message:optimistic", (msg) => {
if (!this.chatId) {
this.chatId = msg.chat_id;
this.shadowRoot.getElementById("chat").textContent = msg.chat_id;
this.shadowRoot.getElementById("meta").textContent = "Nueva conversación";
}
if (msg.chat_id !== this.chatId) return;
this.addOptimisticItem(msg);
});
}
disconnectedCallback() {
@@ -95,6 +108,7 @@ class ConversationInspector extends HTMLElement {
this._unsubLayout?.();
this._unsubScroll?.();
this._unsubSelectMessage?.();
this._unsubOptimistic?.();
this.pause();
}
@@ -180,6 +194,14 @@ class ConversationInspector extends HTMLElement {
metaEl.textContent = `Inspector de ${this.messages.length} mensajes.`;
countEl.textContent = this.messages.length ? `${this.messages.length} filas` : "";
// Preserve optimistic items before clearing
const optimisticItems = [...list.querySelectorAll('.item[data-message-id^="optimistic-"]')];
// Obtener timestamps de mensajes IN del servidor para comparar
const serverInTimestamps = this.messages
.filter(m => m.direction === "in")
.map(m => new Date(m.ts).getTime());
list.innerHTML = "";
this.rowMap.clear();
this.rowOrder = [];
@@ -196,7 +218,7 @@ class ConversationInspector extends HTMLElement {
const intent = run?.llm_output?.intent || "—";
const nextState = run?.llm_output?.next_state || "—";
const prevState = row.nextRun?.prev_state || "—";
const basket = run?.llm_output?.basket_resolved?.items || [];
const basket = run?.llm_output?.full_basket?.items || run?.llm_output?.basket_resolved?.items || [];
const tools = this.toolSummary(run?.tools || []);
const llmMeta = run?.llm_output?._llm || null;
@@ -237,6 +259,23 @@ class ConversationInspector extends HTMLElement {
this.rowMap.set(msg.message_id, el);
this.rowOrder.push(msg.message_id);
}
// Re-add preserved optimistic items ONLY if no server message covers it
for (const optItem of optimisticItems) {
// Obtener timestamp del optimista (está en el ID: optimistic-{timestamp})
const msgId = optItem.dataset.messageId;
const optTs = parseInt(msgId.replace("optimistic-", ""), 10) || 0;
// Si hay un mensaje del servidor con timestamp cercano (10 seg), no re-agregar
const hasServerMatch = serverInTimestamps.some(ts => Math.abs(ts - optTs) < 10000);
if (hasServerMatch) {
continue;
}
list.appendChild(optItem);
this.rowMap.set(msgId, optItem);
this.rowOrder.push(msgId);
}
}
applyHeights() {
@@ -302,6 +341,44 @@ class ConversationInspector extends HTMLElement {
this.highlight(messageId);
this._playIdx += 1;
}
addOptimisticItem(msg) {
const list = this.shadowRoot.getElementById("list");
if (!list) return;
// Remove any existing optimistic item
const existing = list.querySelector(`.item[data-message-id^="optimistic-"]`);
if (existing) existing.remove();
const el = document.createElement("div");
el.className = "item in";
el.dataset.messageId = msg.message_id;
el.innerHTML = `
<div class="kv">
<div class="k">IN</div>
<div class="v">${new Date(msg.ts).toLocaleString()}</div>
<div class="k">STATE</div>
<div class="v">—</div>
<div class="k">INTENT</div>
<div class="v">—</div>
<div class="k">NLU</div>
<div class="v">procesando...</div>
</div>
<div class="cart"><strong>Carrito:</strong> —</div>
<div class="chips"></div>
`;
list.appendChild(el);
list.scrollTop = list.scrollHeight;
this.rowMap.set(msg.message_id, el);
this.rowOrder.push(msg.message_id);
// Apply min height
el.style.minHeight = "120px";
el.style.marginBottom = "12px";
}
}
customElements.define("conversation-inspector", ConversationInspector);