Volver a la wiki

Oráculo de EL — UI híbrida de búsqueda y respuesta sintetizada (s72)

Oráculo de EL — UI híbrida de búsqueda y respuesta sintetizada (s72)

Resumen

El commit s72 (PR #51, cableado con PR #50) extiende el componente SearchInline del shell del Workspace para convertirlo en una caja de búsqueda híbrida: mantiene la búsqueda fuzzy local (Fuse.js) y añade un nuevo modo Oráculo que lanza una pregunta al endpoint POST /api/oraculo/ask, recibe una respuesta sintetizada por Gemma 4 con grounding sobre el grafo completo del Bibliotecario, y la renderiza con Markdown en un panel inline dentro del dropdown de búsqueda.

Cierra la Fase 1 del plan Oráculo de EL.


Modos de búsqueda

ModoTriggerBackendLatencia típica
searchSiempre (manual o auto cuando la query parece término corto)Fuse.js local sobre /search-index.json~0 ms (local)
oracleAuto cuando la query “parece pregunta”; o forzado por chipPOST /api/oraculo/ask → Gemma 4 + grafo Bibliotecario1–3 s
auto(default) Delega a shouldAskOracle()Cualquiera de los dos según heurísticavariable

Heurística shouldAskOracle()

Una query activa el modo Oráculo si cualquiera de estas condiciones se cumple (y tiene ≥ 8 caracteres):

El mínimo de 8 caracteres evita disparar llamadas al modelo para queries cortas como "racks" o "api".


Toggle manual (chips)

En el header del dropdown aparecen tres chips: Auto · Buscar · Preguntar.

El modo se guarda en state local de React; no persiste entre sesiones (intencional en Fase 1).


Flujo de red del Oráculo

Usuario teclea → debounce 450 ms → shouldAskOracle() → true
  → AbortController nuevo (cancela request anterior si existe)
  → POST /api/oraculo/ask { question: <query> }
  → Responde OracleResponse { answer, sources[], model, chunks_used, duration_ms }
  → marked.parse(answer) → dangerouslySetInnerHTML
  → Chips de fuentes (linkables si source_path ↔ /wiki/<slug>)

Cancelación: cada vez que el usuario sigue tecleando antes de los 450 ms, el timer se limpia y el AbortController del request anterior se llama con .abort(). Evita tormenta de llamadas a Gemma 4.

Interfaz OracleResponse

interface OracleResponse {
  answer: string;        // Markdown libre generado por Gemma 4
  sources: OracleSource[]; // Fragmentos del grafo usados como grounding
  model: string;         // e.g. "gemma-4-26b-a4b-it"
  chunks_used: number;
  duration_ms: number;
}

interface OracleSource {
  title: string;
  path: string | null;   // Ruta en el repo (puede ser null)
  chunkTitle: string;
  relevance: number;
}

Renderizado de la respuesta


Chips de fuentes

La función sourceToHref(path) intenta mapear el source_path devuelto por el Oráculo a una URL navegable del Workspace:

Patrón de pathURL generada
src/content/wiki/<slug>.md/wiki/<slug>
wiki/<slug>.md/wiki/<slug>
Cualquier otronull (chip informativo sin link)

Las fuentes con link se renderizan como <a> con clase search-inline-oracle-chip linkable; las demás como <span>.


Cambios CSS (globals.css)


Estado y roadmap

FaseEstadoDescripción
Fase 1✅ Completada (s72)UI híbrida + cable con /api/oraculo/ask
Fase 2⬜ PendienteCorpus completo (todas las secciones del grafo)
Fase 3⬜ PendienteIteración de prompt según feedback de uso real

Dependencias añadidas

PaqueteUso
markedParse de Markdown en respuestas del Oráculo. Ya usado en NoteEditor.

Véase también

Subir