Improve scope handling in RAG playground
This commit is contained in:
parent
6557aea0bc
commit
02798085b1
2 changed files with 71 additions and 14 deletions
|
|
@ -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 = `<option value="">Error cargando scopes: ${error}</option>`;
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -27,7 +27,13 @@
|
|||
<article class="panel">
|
||||
<h2>Ingesta</h2>
|
||||
<div class="grid single-grid">
|
||||
<label>Source ID / scope custom
|
||||
<label>Crear scope aislado
|
||||
<select id="ingestScopeMode">
|
||||
<option value="existing">usar generacion automatica</option>
|
||||
<option value="custom">definir sourceId propio</option>
|
||||
</select>
|
||||
</label>
|
||||
<label id="ingestSourceIdWrapper">Source ID / scope custom
|
||||
<input id="ingestSourceId" placeholder="ej: src:cliente-a:manual:pdf-tecnico" />
|
||||
</label>
|
||||
<label>Tipo de fuente
|
||||
|
|
@ -69,6 +75,9 @@
|
|||
<option value="">Cargando scopes...</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Source ID seleccionado
|
||||
<input id="selectedSourceId" readonly />
|
||||
</label>
|
||||
<label>Scope por sourceRef
|
||||
<input id="scopeSourceRef" value="/home/pancho/Documentos/Empresa/Desarrollo/IA/docs" />
|
||||
</label>
|
||||
|
|
@ -82,6 +91,12 @@
|
|||
<option value="auto">auto</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Edicion manual del scope
|
||||
<select id="scopeEditMode">
|
||||
<option value="locked">bloqueado al scope seleccionado</option>
|
||||
<option value="manual">editar manualmente</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Modelo para sintetizar bootstrap
|
||||
<select id="answerModel">
|
||||
<option value="openai/gpt-4.1-mini">openai/gpt-4.1-mini</option>
|
||||
|
|
@ -119,6 +134,10 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<label>Scope activo para chat
|
||||
<input id="chatScopeInfo" readonly />
|
||||
</label>
|
||||
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="reuseBootstrapContext" checked />
|
||||
Reutilizar bootstrap como contexto base
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue