diff --git a/RAG/public/playground/app.js b/RAG/public/playground/app.js index 8f1af1f..67fab2d 100644 --- a/RAG/public/playground/app.js +++ b/RAG/public/playground/app.js @@ -21,6 +21,8 @@ const contextStatusText = document.getElementById("contextStatusText"); const contextScopeText = document.getElementById("contextScopeText"); const ingestSourceType = document.getElementById("ingestSourceType"); +const ingestScopeMode = document.getElementById("ingestScopeMode"); +const ingestSourceIdWrapper = document.getElementById("ingestSourceIdWrapper"); const ingestSourceId = document.getElementById("ingestSourceId"); const ingestSourceRef = document.getElementById("ingestSourceRef"); const ingestUploadFile = document.getElementById("ingestUploadFile"); @@ -35,14 +37,18 @@ const useModelInRetrieve = document.getElementById("useModelInRetrieve"); const reuseBootstrapContext = document.getElementById("reuseBootstrapContext"); const allowAdditionalRetrieve = document.getElementById("allowAdditionalRetrieve"); const scopePresetSelect = document.getElementById("scopePresetSelect"); +const selectedSourceId = document.getElementById("selectedSourceId"); const scopeSourceRef = document.getElementById("scopeSourceRef"); const scopeTags = document.getElementById("scopeTags"); +const scopeEditMode = document.getElementById("scopeEditMode"); const compareWithoutRag = document.getElementById("compareWithoutRag"); const chatMode = document.getElementById("chatMode"); +const chatScopeInfo = document.getElementById("chatScopeInfo"); const chatInput = document.getElementById("chatInput"); let lastBootstrapContext = null; let chatHistory = []; +let availableScopes = []; function format(value) { return JSON.stringify(value, null, 2); @@ -62,6 +68,7 @@ function updateIngestUiState() { ingestSourceType.value = hasUpload ? "file" : ingestSourceType.value; ingestSourceType.disabled = hasUpload; ingestSourceRef.disabled = hasUpload; + ingestSourceIdWrapper.style.display = ingestScopeMode.value === "custom" ? "block" : "none"; if (hasUpload) { ingestModeHint.textContent = `Upload directo activo: se ingerira el archivo local "${ingestUploadFile.files[0].name}" y se ignorara la ruta manual.`; @@ -72,6 +79,27 @@ function updateIngestUiState() { } } +function applySelectedScope(scope) { + selectedSourceId.value = scope?.sourceId || ""; + scopeSourceRef.value = scope?.sourceRef || ""; + scopeTags.value = (scope?.tags || []).join(", "); + chatScopeInfo.value = [scope?.sourceId, scope?.sourceRef].filter(Boolean).join(" | "); + + if (scope?.chunkModes?.includes("codigo")) { + bootstrapMode.value = "codigo"; + chatMode.value = "codigo"; + } else if (scope?.chunkModes?.includes("documental")) { + bootstrapMode.value = "documental"; + chatMode.value = "documental"; + } +} + +function updateScopeEditState() { + const locked = scopeEditMode.value !== "manual"; + scopeSourceRef.readOnly = locked; + scopeTags.readOnly = locked; +} + function request(url, payload, method = "POST") { return fetch(url, { method, @@ -94,6 +122,7 @@ function renderBootstrapContext() { contextIndicator.className = "indicator indicator-off"; contextStatusText.textContent = "Sin contexto cargado"; contextScopeText.textContent = "No hay bootstrap activo."; + chatScopeInfo.value = [selectedSourceId.value, scopeSourceRef.value].filter(Boolean).join(" | ") || "Sin scope seleccionado"; return; } @@ -101,6 +130,7 @@ function renderBootstrapContext() { contextIndicator.className = "indicator indicator-on"; contextStatusText.textContent = "Contexto bootstrap activo"; contextScopeText.textContent = lastBootstrapContext.scope?.sourceRef || "Scope no especificado"; + chatScopeInfo.value = [lastBootstrapContext.scope?.sourceId, lastBootstrapContext.scope?.sourceRef].filter(Boolean).join(" | "); } function renderChatHistory() { @@ -120,7 +150,17 @@ function renderChatHistory() { } function buildScopeFromInputs() { + if (scopeEditMode.value !== "manual" && scopePresetSelect.value) { + const scope = JSON.parse(scopePresetSelect.value); + return { + sourceId: scope.sourceId, + sourceRef: scope.sourceRef, + tags: scope.tags || [] + }; + } + return { + sourceId: selectedSourceId.value || undefined, sourceRef: scopeSourceRef.value, tags: splitTags(scopeTags.value) }; @@ -137,6 +177,7 @@ function applyPreset(mode, query, sourceRef, useRetrieveModel = false) { async function loadScopes() { try { const scopes = await fetch("/sources").then((response) => response.json()); + availableScopes = scopes; scopePresetSelect.innerHTML = ""; const placeholder = document.createElement("option"); @@ -153,6 +194,9 @@ async function loadScopes() { if (scopes.length === 0) { placeholder.textContent = "No hay scopes detectados"; + } else if (!scopePresetSelect.value) { + scopePresetSelect.value = JSON.stringify(scopes[0]); + applySelectedScope(scopes[0]); } } catch (error) { scopePresetSelect.innerHTML = ``; @@ -192,19 +236,12 @@ scopePresetSelect.addEventListener("change", () => { } const scope = JSON.parse(scopePresetSelect.value); - scopeSourceRef.value = scope.sourceRef || ""; - scopeTags.value = (scope.tags || []).join(", "); - - if (scope.chunkModes.includes("codigo")) { - bootstrapMode.value = "codigo"; - chatMode.value = "codigo"; - } else if (scope.chunkModes.includes("documental")) { - bootstrapMode.value = "documental"; - chatMode.value = "documental"; - } + applySelectedScope(scope); }); ingestUploadFile.addEventListener("change", updateIngestUiState); +ingestScopeMode.addEventListener("change", updateIngestUiState); +scopeEditMode.addEventListener("change", updateScopeEditState); healthButton.addEventListener("click", async () => { healthResult.textContent = "Comprobando..."; @@ -226,7 +263,7 @@ ingestButton.addEventListener("click", async () => { formData.append("file", ingestUploadFile.files[0]); formData.append("mode", ingestMode.value); formData.append("tags", splitTags(ingestTags.value).join(",")); - if (ingestSourceId.value.trim()) { + if (ingestScopeMode.value === "custom" && ingestSourceId.value.trim()) { formData.append("sourceId", ingestSourceId.value.trim()); } @@ -240,7 +277,7 @@ ingestButton.addEventListener("click", async () => { } } else { data = await request("/ingest", { - sourceId: ingestSourceId.value.trim() || undefined, + sourceId: ingestScopeMode.value === "custom" ? (ingestSourceId.value.trim() || undefined) : undefined, sourceType: ingestSourceType.value, sourceRef: ingestSourceRef.value, mode: ingestMode.value, @@ -369,3 +406,4 @@ loadAnswerModels(); renderBootstrapContext(); renderChatHistory(); updateIngestUiState(); +updateScopeEditState(); diff --git a/RAG/public/playground/index.html b/RAG/public/playground/index.html index 04fa9d2..43851a8 100644 --- a/RAG/public/playground/index.html +++ b/RAG/public/playground/index.html @@ -27,7 +27,13 @@

Ingesta

- + +