Store bootstrap metadata in evaluation logs

This commit is contained in:
Paco POR-CORREO 2026-04-06 20:36:14 +02:00
parent 8ce0d7223b
commit c34bc3b5d7
4 changed files with 52 additions and 1 deletions

View file

@ -50,6 +50,7 @@ const chatInput = document.getElementById("chatInput");
const manualLogNote = document.getElementById("manualLogNote");
let lastBootstrapContext = null;
let lastBootstrapMeta = null;
let chatHistory = [];
let availableScopes = [];
let lastInteraction = null;
@ -320,6 +321,13 @@ async function executeBootstrap() {
});
lastBootstrapContext = data;
lastBootstrapMeta = {
query: bootstrapQuery.value,
mode: bootstrapMode.value,
scope: buildScopeFromInputs(),
model: answerModel.value,
usedModelSummary: useModelInRetrieve.checked
};
bootstrapResult.textContent = format(data);
renderBootstrapContext();
lastInteraction = {
@ -330,6 +338,7 @@ async function executeBootstrap() {
model: answerModel.value,
scope: buildScopeFromInputs(),
usedBootstrapContext: false,
bootstrapMeta: lastBootstrapMeta,
usedAdditionalRetrieve: useModelInRetrieve.checked,
responseSummary: data.modelSummary || data.summary,
retrievedItems: data.items || []
@ -345,6 +354,7 @@ replaceBootstrapButton.addEventListener("click", executeBootstrap);
clearBootstrapButton.addEventListener("click", () => {
lastBootstrapContext = null;
lastBootstrapMeta = null;
renderBootstrapContext();
});
@ -368,6 +378,7 @@ sendChatButton.addEventListener("click", async () => {
preloadedContext: reuseBootstrapContext.checked && lastBootstrapContext
? (lastBootstrapContext.modelSummary || lastBootstrapContext.summary || "")
: undefined,
bootstrapMeta: reuseBootstrapContext.checked ? lastBootstrapMeta : undefined,
allowAdditionalRetrieve: allowAdditionalRetrieve.checked,
scope: buildScopeFromInputs()
});
@ -383,6 +394,7 @@ sendChatButton.addEventListener("click", async () => {
model: answerModel.value,
scope: buildScopeFromInputs(),
usedBootstrapContext: response.usedBootstrapContext,
bootstrapMeta: reuseBootstrapContext.checked ? lastBootstrapMeta : undefined,
usedAdditionalRetrieve: response.usedAdditionalRetrieve,
responseSummary: response.answer,
retrievedItems: response.retrieved?.items || []
@ -395,7 +407,8 @@ sendChatButton.addEventListener("click", async () => {
model: answerModel.value,
preloadedContext: reuseBootstrapContext.checked && lastBootstrapContext
? (lastBootstrapContext.modelSummary || lastBootstrapContext.summary || "")
: undefined
: undefined,
bootstrapMeta: reuseBootstrapContext.checked ? lastBootstrapMeta : undefined
});
compareResult.textContent = format(comparison);
}

View file

@ -42,6 +42,21 @@ export function createApp() {
return /no se recupero contexto|no hay informacion suficiente|no dispongo de mas detalles|contexto insuficiente/i.test(text);
}
function parseBootstrapMeta(input: unknown) {
if (!input || typeof input !== "object") {
return {};
}
const value = input as Record<string, unknown>;
return {
bootstrapQuery: value.query ? String(value.query) : undefined,
bootstrapMode: value.mode as ChunkMode | undefined,
bootstrapScope: value.scope as RetrieveScope | undefined,
bootstrapModel: value.model ? String(value.model) : undefined,
bootstrapUsedModelSummary: Boolean(value.usedModelSummary)
};
}
app.use(express.json({ limit: "5mb" }));
app.use(express.static(publicDir));
@ -155,6 +170,7 @@ export function createApp() {
const query = String(req.body.query ?? "");
const model = req.body.model ? String(req.body.model) : undefined;
const useModel = Boolean(req.body.useModelInRetrieve);
const bootstrapMeta = parseBootstrapMeta(req.body.bootstrapMeta);
const scope: RetrieveScope | undefined = req.body.scope
? {
sourceId: req.body.scope.sourceId,
@ -182,6 +198,7 @@ export function createApp() {
intent,
scope,
model: payload.model,
...bootstrapMeta,
responseSummary: payload.modelSummary,
retrievedItems: items
});
@ -200,6 +217,7 @@ export function createApp() {
mode,
intent,
scope,
...bootstrapMeta,
responseSummary: result.summary,
retrievedItems: items
});
@ -225,6 +243,7 @@ export function createApp() {
: undefined;
const model = req.body.model ? String(req.body.model) : undefined;
const preloadedContext = req.body.preloadedContext ? String(req.body.preloadedContext) : undefined;
const bootstrapMeta = parseBootstrapMeta(req.body.bootstrapMeta);
const result = await answerService.answer(mode, intent, query, scope, model, preloadedContext);
if (needsContextLog(result.summary, result.citations.length, result.answer)) {
@ -239,6 +258,7 @@ export function createApp() {
model: result.model,
note: preloadedContext ? "bootstrap_context_present" : undefined,
usedBootstrapContext: Boolean(preloadedContext),
...bootstrapMeta,
responseSummary: result.answer,
retrievedItems: result.citations.map((citation) => ({
chunkId: citation.chunkId,
@ -278,6 +298,7 @@ export function createApp() {
const mode = (req.body.mode ?? "documental") as ChunkMode;
const model = req.body.model ? String(req.body.model) : undefined;
const preloadedContext = req.body.preloadedContext ? String(req.body.preloadedContext) : undefined;
const bootstrapMeta = parseBootstrapMeta(req.body.bootstrapMeta);
const allowAdditionalRetrieve = Boolean(req.body.allowAdditionalRetrieve);
const historyEntries = Array.isArray(req.body.history) ? req.body.history as Array<{ role?: string; content?: unknown }> : [];
const history: ChatMessage[] = historyEntries.length > 0
@ -317,6 +338,7 @@ export function createApp() {
scope,
model: result.model,
usedBootstrapContext: result.usedBootstrapContext,
...bootstrapMeta,
usedAdditionalRetrieve: result.usedAdditionalRetrieve,
responseSummary: result.answer,
retrievedItems: result.retrieved?.items ?? []
@ -343,6 +365,7 @@ export function createApp() {
model: req.body.model,
note: req.body.note ? `Log solicitado por el usuario. Nota: ${String(req.body.note)}` : "Log solicitado por el usuario.",
usedBootstrapContext: Boolean(req.body.usedBootstrapContext),
...parseBootstrapMeta(req.body.bootstrapMeta),
usedAdditionalRetrieve: Boolean(req.body.usedAdditionalRetrieve),
responseSummary: req.body.responseSummary ? String(req.body.responseSummary) : undefined,
retrievedItems: Array.isArray(req.body.retrievedItems) ? req.body.retrievedItems : []

View file

@ -36,6 +36,11 @@ export class EvaluationLogService {
createdAt: new Date().toISOString(),
scope: input.scope,
usedBootstrapContext: input.usedBootstrapContext,
bootstrapQuery: input.bootstrapQuery,
bootstrapMode: input.bootstrapMode,
bootstrapScope: input.bootstrapScope,
bootstrapModel: input.bootstrapModel,
bootstrapUsedModelSummary: input.bootstrapUsedModelSummary,
usedAdditionalRetrieve: input.usedAdditionalRetrieve,
responseSummary: input.responseSummary,
retrievedItemsCount: input.retrievedItems?.length ?? 0,

View file

@ -117,6 +117,11 @@ export interface EvaluationLogInput {
model?: string;
note?: string;
usedBootstrapContext?: boolean;
bootstrapQuery?: string;
bootstrapMode?: ChunkMode;
bootstrapScope?: RetrieveScope;
bootstrapModel?: string;
bootstrapUsedModelSummary?: boolean;
usedAdditionalRetrieve?: boolean;
responseSummary?: string;
retrievedItems?: RetrievedItem[];
@ -135,6 +140,11 @@ export interface EvaluationLogEntry {
createdAt: string;
scope?: RetrieveScope;
usedBootstrapContext?: boolean;
bootstrapQuery?: string;
bootstrapMode?: ChunkMode;
bootstrapScope?: RetrieveScope;
bootstrapModel?: string;
bootstrapUsedModelSummary?: boolean;
usedAdditionalRetrieve?: boolean;
responseSummary?: string;
retrievedItemsCount: number;